54

我有一个基类Person和派生类Manager以及Employee. 现在,我想知道的是创建的对象是ManagerEmployee.

该人如下:

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它时,它要么ManagerEmployee. 当我得到 person 对象时,类是 Person,但我想知道它是来自派生类“Manager”还是“Employee”。

4

7 回答 7

57

我不知道这是否是您想要的,以及您希望它实现的方式,但这里有一个尝试:

>>> 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方法定义。

于 2012-07-10T07:23:33.590 回答
13

您可以使用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"
于 2012-07-10T07:22:27.303 回答
9

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'
于 2012-07-10T07:22:44.603 回答
8

你会寻找这样的东西吗?

>>> 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
于 2012-07-10T08:37:22.757 回答
4

“这样做”的最好方法是不这样做。相反,在 Person 上创建可在 Manager 或 Employee 上覆盖的方法,或者为子类提供自己的扩展基类的方法。

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 的新子类,你会怎么做?当子类不是它所知道的任何硬编码替代品时,Person 会做什么?

于 2012-07-10T07:29:42.180 回答
0

在您的示例中,您不需要知道类,只需通过引用类实例来调用方法:

# 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用作变量名,你隐藏了内置名称。

于 2012-07-10T08:35:20.387 回答
0

Python 类有一个__subclasses__神奇的方法,可以用来查看当前哪些范围内的类是从给定的父类派生的。

# related.py

class Parent: ...

class Child(Parent): ...
>>> from related import Parent
>>> Parent.__subclasses__()
[<class 'related.Child'>]

在访问类时,这些类是对任何范围内派生类的弱引用Parent

# not_related.py

class StepChild(Parent): ...
>>> from related import Parent
>>> Parent.__subclasses__()
[<class '__main__.Child'>]
>>> from not_related import StepChild
>>> Parent.__subclasses__()
[<class 'related.Child'>, <class 'not_related.StepChild'>]
于 2021-12-02T20:40:11.223 回答