2012-07-10 72 views
21

我有一个基类Person和派生类ManagerEmployee。现在,我想知道的是创建的对象是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,但我想知道它是来自派生类“经理”还是“员工”。

+0

你能提出一些代码来证明你想要做什么吗? – SuperSaiyan 2012-07-10 07:07:11

回答

4

不完全相信我明白你在问什么,但是你可以用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" 
6

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' 
+0

我认为你正在回答正确的问题。 – yaobin 2016-07-18 15:24:15

27

我不知道如果这是您想要的,以及您希望实施的方式,但是这里是一个尝试:

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

+0

简洁。很好地使用交互式输出。 – 2016-08-06 08:47:32

+0

非常感谢..这就是我一直在寻找的! – 2017-03-16 09:55:51

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

+0

令人怀疑这是“最好的方式”,或者OP的设计已经破损。如[回答](http://stackoverflow.com/a/11408458/355230)所示,实现起来更简单,其中基类具有所有子类可以使用的方法(无论用户选择什么目的)。 – martineau 2016-12-26 22:40:07

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作为变量名,你隐藏内置在名义上。

3

您是否在寻找类似的东西?

>>> 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