web-dev-qa-db-fra.com

comment obtenir le nom de classe dérivé de la classe de base

J'ai une classe de base Person et des classes dérivées Manager et Employee. Maintenant, ce que je voudrais savoir, c'est que l'objet créé est Manager ou Employee.

La personne est donnée comme ci-dessous:

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

Pour le manager et les employés, ils sont similaires (l'employé est également similaire mais certaines méthodes sont différentes)

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

Pour l'employé, le titre est "employé". Quand je crée un Person c'est soit Manager soit le Employee. Lorsque j'obtiens l'objet personne, la classe est Personne, mais j'aimerais savoir si elle provient de la classe dérivée "Manager" ou "Employé".

34
Sadiksha Gautam

Je ne sais pas exactement si je comprends ce que vous demandez, mais vous pouvez utiliser x.__class__.__name__ pour récupérer le nom de la classe sous forme de chaîne, par exemple.

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

Ou, vous pouvez utiliser isinstance pour vérifier différents types:

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

Vous pouvez donc faire quelque chose comme ceci:

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

Je ne sais pas si c'est ce que vous voulez et la façon dont vous aimeriez l'implémenter, mais voici un essai:

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


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

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

Avantages: une seule définition du _type méthode.

40
Emmanuel

Les objets Python fournissent un __class__ attribut qui stocke le type utilisé pour créer cet objet. Ceci fournit à son tour un __name__ attribut qui peut être utilisé pour obtenir le nom du type sous forme de chaîne. Donc, dans le cas simple:

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

b = B()
print b.__class__.__name__

Donnerait:

'B'

Donc, si je suis bien votre question, vous feriez:

m = Manager()
print m.__class__.__name__
'Manager'
8
Mark Streatfield

Souhaitez-vous rechercher quelque chose comme ça?

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

La meilleure façon de "faire cela" est de ne pas le faire. Au lieu de cela, créez des méthodes sur Person qui sont remplacées sur Manager ou Employee, ou donnez aux sous-classes leurs propres méthodes qui étendent la classe de 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"

Si vous avez besoin de savoir dans la classe de base quelle sous-classe est instanciée, votre programme a probablement une erreur de conception. Que ferez-vous si quelqu'un d'autre étend ultérieurement Personne pour ajouter une nouvelle sous-classe appelée Entrepreneur? Que fera Personne lorsque la sous-classe n'est pas l'une des alternatives codées en dur qu'elle connaît?

4
BrenBarn

Dans votre exemple, vous n'avez pas besoin de connaître la classe, vous appelez simplement la méthode en vous référant à l'instance de 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()

Mais n'utilisez pas object comme nom de variable, vous masquez le nom intégré.

0
Janne Karila