簡體   English   中英

如何從基類獲取派生類名

[英]how to get derived class name from base class

我有一個基類Person和派生類ManagerEmployee 現在,我想知道創建的對象是Manager還是Employee

此人如下:

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

對於Manager和employee來說是一樣的(employee也是相似的,只是方法不同)

from Project.Person import Person
class Manager(Person):
    def title(self):
      return "Manager"

對於員工,標題是“員工”。 當我創建一個Person它是ManagerEmployee 當我獲得 person 對象時,該類是 Person 但我想知道它是來自派生類“Manager”還是“Employee”。

我不知道這是否是您想要的,以及您希望它的實現方式,但可以嘗試一下:

>>> 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方法只有一個定義。

您可以使用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"

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'

你會尋找這樣的東西嗎?

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

“做這個”最好的辦法就是不做。 相反,在 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 會做什么?

在您的示例中,您不需要知道該類,您只需通過引用類實例來調用該方法:

# 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作為變量名,你隱藏了內置名稱。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM