python multiple inheritance
cómo obtener el nombre de clase derivado de la clase base (6)
Tengo una clase base Person
y clases derivadas Manager
y Employee
. Ahora, lo que me gustaría saber es que el objeto creado es el Manager
o el Employee
.
La persona es dada 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 el Gerente y los empleados son como (el empleado también es similar pero con algunos métodos diferentes)
from Project.Person import Person
class Manager(Person):
def title(self):
return "Manager"
Para Empleado el título es ''Empleado''. Cuando creo una Person
, es el Manager
o el Employee
. Cuando obtengo el objeto person, la clase es Person, pero me gustaría saber si es de la clase derivada ''Manager'' o ''Employee''.
¿Estarías 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
En su ejemplo, no necesita conocer la clase, simplemente llame al método refiriéndose a la instancia de la 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 use el object
como un nombre de variable, oculta el nombre incorporado.
La mejor manera de "hacer esto" es no hacerlo. En su lugar, cree métodos en Persona que se invaliden en Manager o Employee, o asigne a las subclases sus propios métodos que amplían 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 necesita saber en la clase base qué subclase se está creando, es probable que su programa tenga un error de diseño. ¿Qué hará si alguien más extiende luego a Persona para agregar una nueva subclase llamada Contratista? ¿Qué hará Person cuando la subclase no sea ninguna de las alternativas codificadas que conoce?
Los objetos de Python proporcionan un atributo __class__
que almacena el tipo utilizado para hacer ese objeto. Esto a su vez proporciona un atributo __name__
que se puede usar 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''
Entonces, si sigo tu pregunta correctamente harías:
m = Manager()
print m.__class__.__name__
''Manager''
No estoy exactamente seguro de que entiendo lo que estás preguntando, pero puedes usar x.__class__.__name__
para recuperar el nombre de la clase como una cadena, por ejemplo
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, podría usar isinstance para verificar diferentes tipos:
>>> print isinstance(m, Person)
True
>>> print isinstance(m, Manager)
True
>>> print isinstance(m, Employee)
False
Así que podrías 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"
No sé si esto es lo que quieres y la forma en que te gustaría que se implementara, pero aquí hay un intento:
>>> 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: solo una definición del método _type
.