2012-07-10 24 views
21

Tengo una clase base Person y las clases derivadas Manager y Employee. Ahora, lo que me gustaría saber es que el objeto creado es Manager o Employee.cómo obtener el nombre de clase derivado de la clase base

La persona se da como belows:

from Project.CMFCore.utils import getToolByName 
schema = getattr(Person, 'schema', Schema(())).copy() + Schema((TextField('FirstName', required = True, widget = StringWidget(label='First Name', i18n_domain='project')), TextField('Last Name', required = True, widget = StringWidget(label='Last Name', i18n_domain='i5', label_msgid='label_pub_city')) 
class Manager(BaseContent): 
    def get_name(self): 
    catalog = getToolByName(self, "portal_catalog") 
     people = catalog(portal_type='Person') 
     person={} 
     for object in people: 
     fname = object.firstName 
     lname = object.lastName 
     person['name'] = fname+' '+ lname 
     # if the derived class is Employee then i would like go to the method title of employee and if its a Manager then go to the title method of Manager 
     person['post'] = Employee/Manager.title() 
     return person 

Para Manager y los empleados son como (empleado también es similar, pero algunos métodos diferentes)

from Project.Person import Person 
class Manager(Person): 
    def title(self): 
     return "Manager" 

para el empleado el título es 'empleado' . Cuando creo un Person, es Manager o Employee. Cuando obtengo el objeto persona la clase es Persona pero me gustaría saber si es de la clase derivada 'Gerente' o 'Empleado'.

+0

¿Puedes poner un código que demuestre exactamente lo que quieres hacer? – SuperSaiyan

Respuesta

4

No estoy exactamente seguro de entender lo que me está preguntando, pero puede usar x.__class__.__name__ para recuperar el nombre de la clase como una cadena, p. Ej.

class Person: 
    pass 

class Manager(Person): 
    pass 

class Employee(Person): 
    pass 

def get_class_name(instance): 
    return instance.__class__.__name__ 

>>> m = Manager() 
>>> print get_class_name(m) 
Manager 
>>> print get_class_name(Employee()) 
Employee 

O bien, puede utilizar isinstance para comprobar si hay diferentes tipos:

>>> print isinstance(m, Person) 
True 
>>> print isinstance(m, Manager) 
True 
>>> print isinstance(m, Employee) 
False 

Por lo que podría hacer algo como esto:

def handle_person(person): 
    if isinstance(person, Manager): 
     person.read_paper()  # method of Manager class only 
    elif isinstance(person, Employee): 
     person.work_hard()  # method of Employee class only 
    elif isinstance(person, Person): 
     person.blah()   # method of the base class 
    else: 
     print "Not a person" 
6

objetos Python proporcionan un atributo __class__ que almacena la tipo utilizado para hacer ese objeto. Esto a su vez proporciona un atributo __name__ que se puede utilizar para obtener el nombre del tipo como una cadena. Así, en el caso simple:

class A(object): 
    pass 
class B(A): 
    pass 

b = B() 
print b.__class__.__name__ 

daría:

'B'

Por lo tanto, si sigo bien su pregunta que haría:

m = Manager() 
print m.__class__.__name__ 
'Manager' 
+0

Creo que está respondiendo la pregunta correcta. – yaobin

27

no sé si esto es lo que quiere, y la forma en que le gustaría implementarlo, pero aquí hay una prueba:

>>> class Person(object): 
    def _type(self): 
     return self.__class__.__name__ 


>>> p = Person() 
>>> p._type() 
'Person' 
>>> class Manager(Person): 
    pass 

>>> m = Manager() 
>>> m._type() 
'Manager' 
>>> 

Pros: una sola definición del método _type.

+0

Sucinto. Buen uso de salida interactiva. –

+0

Muchas gracias ... ¡Esto es lo que estaba buscando! –

4

La mejor manera de "hacer esto" es no hacerlo. En su lugar, cree métodos en Person que estén anulados en Manager o Employee, o proporcióneles a las subclases sus propios métodos que amplíen la clase base.

class Person(object): 
    def doYourStuff(self): 
     print "I'm just a person, I don't have anything to do" 

class Manager(object): 
    def doYourStuff(self): 
     print "I hereby manage you" 

class Employee(object): 
    def doYourStuff(self): 
     print "I work long hours" 

Si ves que necesitas saber de la clase base que se está subclase instancia, su programa tiene probablemente un error de diseño. ¿Qué harás si alguien más extiende a Persona para agregar una nueva subclase llamada Contratista? ¿Qué hará la Persona cuando la subclase no sea una de las alternativas codificadas que conoce?

+0

Dudoso que esta es la "mejor manera" o que el OP tiene un diseño roto. Más fácil de implementar como se muestra en [esta respuesta] (http://stackoverflow.com/a/11408458/355230) en el que la clase base tiene un método que todas las subclases pueden usar (para el propósito que elijan). – martineau

0

En su ejemplo que no es necesario saber la clase, que acaba de llamar el método haciendo referencia a la instancia de clase:

# if the derived class is Employee then i would like go to the method title 
# of employee and if its a Manager then go to the title method of Manager 
person['post'] = object.title() 

Pero no utiliza object como nombre de variable, se oculta la incorporada en nombre.

3

¿Estaría buscando algo como esto?

>>> class Employee: 
...  pass 
... 
>>> class Manager(Employee): 
...  pass 
... 
>>> e = Employee() 
>>> m = Manager() 
>>> print e.__class__.__name__ 
Employee 
>>> print m.__class__.__name__ 
Manager 
>>> e.__class__.__name__ == 'Manager' 
False 
>>> e.__class__.__name__ == 'Employee' 
True 
Cuestiones relacionadas