2012-07-10 18 views
21

Ho una classe basee classi derivate Manager e Employee. Ora, quello che vorrei sapere è che l'oggetto creato è Manager o Employee.come ottenere il nome della classe derivata dalla classe base

La persona viene dato come 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 

Per Manager e dipendenti sono come (dipendente è anche simile, ma alcuni metodi diversi)

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

Per i dipendenti il ​​titolo è 'dipendenti' . Quando creo un Person è Manager o Employee. Quando ottengo l'oggetto persona, la classe è Persona, ma vorrei sapere se proviene dalla classe derivata "Manager" o "Dipendente".

+0

Puoi mettere un po 'di codice per dimostrare esattamente cosa vuoi fare? – SuperSaiyan

risposta

4

Non esattamente sicuro di aver capito cosa stai chiedendo, ma puoi usare x.__class__.__name__ per recuperare il nome della classe come una stringa, ad es.

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 

Oppure, si potrebbe utilizzare isinstance per verificare la presenza di diverse tipologie:

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

Così si potrebbe fare qualcosa di simile:

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

oggetti Python forniscono un attributo __class__ che memorizza la tipo utilizzato per rendere quell'oggetto. Questo a turno fornisce un attributo __name__ che può essere utilizzato per ottenere il nome del tipo come una stringa. Così, nel caso semplice:

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

b = B() 
print b.__class__.__name__ 

Otterrà:

'B'

Quindi, se seguo correttamente la vostra domanda si dovrebbe fare:

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

Penso che tu stia rispondendo alla domanda corretta. – yaobin

27

non so se questo è ciò che desideri e come vorresti fosse implementato, ecco una prova:

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


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

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

Pro: solo una definizione del metodo _type.

+0

Succinto. Buon uso dell'output interattivo. –

+0

Molte grazie .. Questo è quello che stavo cercando! –

4

Il modo migliore per "fare questo" è non farlo. Invece, crea metodi su Persona che sono sovrascritti su Manager o Dipendente, o dai loro metodi che estendono la classe base.

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" 

Se vi trovate a dover conoscere nella classe base, che sottoclasse viene istanziato, il programma ha probabilmente un errore di progettazione. Cosa farai se qualcun altro successivamente estenderà la persona per aggiungere una nuova sottoclasse chiamata Contractor? Cosa farà la persona quando la sottoclasse non è una delle alternative hard-coded di cui è a conoscenza?

+0

Dubbi che questo è il "modo migliore" o che l'OP ha un design rotto. Più semplice da implementare come mostrato in [questa risposta] (http://stackoverflow.com/a/11408458/355230) in cui la classe base ha un metodo che tutte le sottoclassi possono utilizzare (per qualsiasi scopo scelgano). – martineau

0

Nel tuo esempio non è necessario conoscere la classe, basta chiamare il metodo facendo riferimento all'istanza di classe:

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

Ma non si utilizza object come un nome di variabile, si nasconde l'incorporato nel nome

3

Vuoi qualcosa di simile?

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