web-dev-qa-db-ja.com

基本クラスから派生クラス名を取得する方法

基本クラスPersonと派生クラスManagerEmployeeがあります。さて、私が知りたいのは、作成されたオブジェクトが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」からのものか知りたいです。

34
Sadiksha Gautam

私があなたが何を求めているのか理解しているとは正確にはわかりませんが、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"
8
mhawke

これがあなたが望むものであるかどうか、そしてあなたがそれを実装したい方法はわかりませんが、ここで試してみます:

>>> 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つの定義のみ。

40
Emmanuel

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'
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
7
Maria Zverina

「これを行う」最善の方法は、行わないことです。代わりに、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は何をしますか?

4
BrenBarn

あなたの例では、クラスを知る必要はありません、あなたはクラスインスタンスを参照することによってメソッドを呼び出すだけです:

# 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を使用しないでください。組み込み名が非表示になります。

0
Janne Karila