Как получить имя производного класса из базового класса
У меня есть базовый класс Person
и производные классы Manager
и Employee
. Теперь, что я хотел бы знать, это созданный объект: Manager
или Employee
.
Человек дается как 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
Для менеджера и сотрудников они похожи (сотрудник тоже похож, но некоторые другие методы)
from Project.Person import Person
class Manager(Person):
def title(self):
return "Manager"
Для сотрудника название - "Сотрудник". Когда я создаю Person
, это либо Manager
, либо Employee
. Когда я получаю объект person, класс является Person, но я хотел бы знать, есть ли он из производного класса "Менеджер" или "Сотрудник".
Ответы
Ответ 1
Я не знаю, действительно ли это то, что вы хотите, и способ, которым вы хотите его реализовать, но вот попытка:
>>> class Person(object):
def _type(self):
return self.__class__.__name__
>>> p = Person()
>>> p._type()
'Person'
>>> class Manager(Person):
pass
>>> m = Manager()
>>> m._type()
'Manager'
>>>
Плюсы: только одно определение метода _type
.
Ответ 2
Объекты Python предоставляют атрибут __class__
, который сохраняет тип, используемый для создания этого объекта. Это по очереди предоставляет атрибут __name__
, который можно использовать для получения имени типа в виде строки. Итак, в простом случае:
class A(object):
pass
class B(A):
pass
b = B()
print b.__class__.__name__
Давал бы:
'B'
Итак, если я правильно следую вашему вопросу, вы бы сделали:
m = Manager()
print m.__class__.__name__
'Manager'
Ответ 3
Не совсем уверен, что я понимаю, что вы просите, но вы можете использовать x.__class__.__name__
для извлечения имени класса в виде строки, например.
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
Или вы можете использовать isinstance для проверки для разных типов:
>>> print isinstance(m, Person)
True
>>> print isinstance(m, Manager)
True
>>> print isinstance(m, Employee)
False
Итак, вы можете сделать что-то вроде этого:
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"
Ответ 4
Лучший способ "сделать это" - не делать этого. Вместо этого создайте методы для Person, которые переопределены в Менеджере или Сотруднике, или дайте подклассам собственные методы, которые расширяют базовый класс.
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"
Если вам нужно знать в базовом классе, какой подкласс создается, ваша программа, вероятно, имеет ошибку проектирования. Что вы сделаете, если кто-то позже расширит Person для добавления нового подкласса под названием Contractor? Что сделает Человек, если подкласс не является одним из жестко запрограммированных альтернатив, о которых он знает?
Ответ 5
Будете ли вы искать что-то вроде этого?
>>> 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
Ответ 6
В вашем примере вам не нужно знать класс, вы просто вызываете метод, ссылаясь на экземпляр класса:
# 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()
Но не используйте object
в качестве имени переменной, вы скрываете встроенное имя.