2012-07-10 14 views
21

Mam klasy bazowej Person i klasy pochodne Manager i Employee. Teraz, co chciałbym wiedzieć, to obiekt stworzony jest Manager lub Employee.jak uzyskać pochodną nazwę klasy z klasy podstawowej

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

dla menedżera i pracowników są jak (pracownik jest podobne, ale kilka różnych metod)

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

Dla Pracownika tytuł brzmi „urzędnik” . Kiedy tworzę Person to albo Manager lub Employee. Kiedy otrzymuję obiekt osoby, klasa jest Person, ale chciałbym wiedzieć, czy pochodzi ona z klasy pochodnej "Manager" lub "Employee".

+0

Czy możesz podać kod, który dokładnie pokazuje, co chcesz zrobić? – SuperSaiyan

Odpowiedz

4

Niezupełnie się, że rozumiem, o co prosicie, ale można użyć x.__class__.__name__ aby pobrać nazwę klasy jako ciąg znaków, na przykład

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 

Albo można użyć isinstance celu sprawdzenia różnych typów:

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

Więc można zrobić coś takiego:

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

obiekty Pythona zapewnić atrybut __class__ przechowująca typ używany do utworzenia tego obiektu. To z kolei dostarcza atrybutu __name__, który może być użyty do uzyskania nazwy typu jako łańcucha. Tak więc, w prostym przypadku:

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

b = B() 
print b.__class__.__name__ 

Dają:

'B'

więc, jeśli śledzę Twoje pytanie poprawnie byś zrobił:

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

Myślę, że odpowiadasz na prawidłowe pytanie. – yaobin

27

nie wiem jeśli to jest to, co chcesz, i sposób, w jaki chcesz to realizowane, ale tu spróbować:

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


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

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

Plusy: tylko jedna definicja metody _type.

+0

Zwięzłe. Dobre wykorzystanie interaktywnego wyjścia. –

+0

Wielkie dzięki. Tego właśnie szukałem! –

4

Najlepszym sposobem „to zrobić” to nie to zrobić. Zamiast tego utwórz metody dla Osoby, które zostały nadpisane w Menedżerze lub Pracowniku, lub nadaj podklasom własne metody rozszerzające klasę podstawową.

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" 

Jeśli znajdziesz się potrzebują wiedzieć, w klasie bazowej, która podklasą jest instancja, program prawdopodobnie ma błąd projektowy. Co zrobisz, jeśli ktoś później rozszerzy osobę, aby dodać nową podklasę o nazwie Wykonawca? Co zrobi osoba, gdy podklasa nie jest żadną z dobrze zakodowanych alternatyw, o których wie?

+0

Wątpliwe, że jest to "najlepszy sposób" lub że OP ma zepsuty projekt. Prostsze do zaimplementowania, jak pokazano w [tej odpowiedzi] (http://stackoverflow.com/a/11408458/355230), w której klasa bazowa ma metodę, którą wszystkie podklasy mogą wykorzystywać (do dowolnego celu, jaki wybiorą). – martineau

0

W przykładzie nie trzeba znać klasę, wystarczy wywołać metodę, odwołując się do instancji klasy:

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

Ale nie używać object jako nazwy zmiennej, ukryć wbudowanej w nazwie.

3

Szukasz czegoś takiego?

>>> 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 
Powiązane problemy