基本クラス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ですが、それが派生クラス「Manager」からのものか「Employee」からのものか知りたいです。
私があなたが何を求めているのか理解しているとは正確にはわかりませんが、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"
これがあなたが望むものであるかどうか、そしてあなたがそれを実装したい方法はわかりませんが、ここで試してみます:
>>> 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
メソッドの1つの定義のみ。
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
「これを行う」最善の方法は、行わないことです。代わりに、ManagerまたはEmployeeでオーバーライドされる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と呼ばれる新しいサブクラスを追加する場合はどうしますか?サブクラスが、それが知っているハードコードされた代替のいずれでもない場合、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
を使用しないでください。組み込み名が非表示になります。