Подтвердить что ты не робот

Как получить имя производного класса из базового класса

У меня есть базовый класс 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, но я хотел бы знать, есть ли он из производного класса "Менеджер" или "Сотрудник".

4b9b3361

Ответ 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 в качестве имени переменной, вы скрываете встроенное имя.