2012-07-10 11 views
21

zu bekommen habe ich eine Basisklasse Person und abgeleiteten Klassen Manager und Employee. Nun möchte ich wissen, dass das Objekt Manager oder Employee erstellt wurde.wie von Basisklasse abgeleitete Klasse Name

Die Person als belows gegeben:

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 

Für Geschäftsführer und Mitarbeiter sie wie sind (Mitarbeiter ist auch ähnlich, aber einige andere Methoden)

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

Für Mitarbeiter ist der Titel ‚Mitarbeiter‘ . Wenn ich ein Person erstelle, ist es entweder Manager oder das Employee. Wenn ich das Person-Objekt erhalte, ist die Klasse Person, aber ich möchte wissen, ob sie aus der abgeleiteten Klasse "Manager" oder "Mitarbeiter" stammt.

+0

Können Sie etwas Code aufstellen, der zeigt, was genau Sie tun möchten? – SuperSaiyan

Antwort

4

Nicht genau sicher, dass ich verstehe, was Sie fragen, aber Sie können x.__class__.__name__ verwenden, um den Klassennamen als Zeichenfolge abzurufen, z.

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 

Oder Sie isinstance für verschiedene Arten überprüfen verwenden:

>>> print isinstance(m, Person) 
True 
>>> print isinstance(m, Manager) 
True 
>>> print isinstance(m, Employee) 
False 

So können Sie etwas tun könnte:

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-Objekte bieten eine __class__ Attribut, das die speichert Typ, der verwendet wird, um das Objekt zu erstellen. Dies wiederum liefert ein __name__ Attribut, das verwendet werden kann, um den Namen des Typs als String zu erhalten. Also, im einfachen Fall:

class A(object): 
    pass 
class B(A): 
    pass 

b = B() 
print b.__class__.__name__ 

würde:

'B'

Also, wenn ich Ihre Frage richtig folgen würden Sie tun:

m = Manager() 
print m.__class__.__name__ 
'Manager' 
+0

Ich denke, dass Sie die richtige Frage beantworten. – yaobin

27

Ich weiß nicht, Wenn dies das ist, was Sie wollen und wie Sie es implementiert haben möchten, aber hier ist ein Versuch:

>>> class Person(object): 
    def _type(self): 
     return self.__class__.__name__ 


>>> p = Person() 
>>> p._type() 
'Person' 
>>> class Manager(Person): 
    pass 

>>> m = Manager() 
>>> m._type() 
'Manager' 
>>> 

Pros: nur eine Definition der _type Methode.

+0

Prägnant. Nette Verwendung der interaktiven Ausgabe. –

+0

Vielen Dank .. Das ist, was ich gesucht habe! –

4

Der beste Weg, dies zu tun ist, es nicht zu tun. Erstellen Sie stattdessen Methoden für Person, die in Manager oder Employee überschrieben werden, oder geben Sie den Unterklassen ihre eigenen Methoden an, die die Basisklasse erweitern.

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" 

Wenn Sie sich in der Basisklasse wissen zu müssen, die Unterklasse instanziiert wird, hat Ihr Programm wahrscheinlich ein Design-Fehler. Was tun Sie, wenn jemand später Person erweitert, um eine neue Unterklasse namens Auftragnehmer hinzuzufügen? Was wird Person tun, wenn die Unterklasse keine der hartcodierten Alternativen ist, von denen sie weiß?

+0

Zweifelhaft, dass dies der "beste Weg" ist oder dass das OP ein gebrochenes Design hat. Einfacher zu implementieren, wie in [diese Antwort] (http://stackoverflow.com/a/11408458/355230) gezeigt, in dem die Basisklasse eine Methode hat, die alle Unterklassen verwenden können (für welchen Zweck sie auch wählen). – martineau

0

In Ihrem Beispiel müssen Sie die Klasse nicht wissen, man muss nur die Methode aufrufen, indem Sie auf die Klasseninstanz verweisen:

# 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() 

Aber nicht object als Variablennamen verwenden, verstecken Sie den integrierten im Namen.

3

Würdest du nach so etwas suchen?

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