1728 votes

Obtenir le nom de classe d'une instance en Python

Comment puis-je trouver le nom de la classe qui a créé l'instance d'un objet en Python si la fonction à partir de laquelle je le fais est la classe de base dont la classe de l'instance a été dérivée ?

Je pensais que peut-être le module d'inspection aurait pu m'aider ici, mais il ne semble pas me donner ce que je veux. Et à défaut d'analyser le __class__ membre, je ne suis pas sûr de savoir comment obtenir cette information.

0 votes

Qu'est-ce que vous "analysez" exactement à partir de l'élément classe variable ?

1 votes

Le nom de premier niveau de la classe à laquelle appartient l'instance (sans nom de module, etc...)

0 votes

Je pense que l'inverse serait beaucoup plus difficile (obtenir la classe dans laquelle la méthode/fonction est définie).

2275voto

sykora Points 30290

Avez-vous essayé le __name__ de la classe ? c'est-à-dire x.__class__.__name__ vous donnera le nom de la classe, ce qui, je pense, est ce que vous voulez.

>>> import itertools
>>> x = itertools.count(0)
>>> x.__class__.__name__
'count'

EDIT : Si vous utilisez des classes de type nouveau (depuis python 2.2, ce qui est presque certainement le cas à l'heure actuelle), vous devez appeler la fonction type() à la place :

>>> type(x).__name__
'count'

Les deux méthodes fonctionnent également pour les types intégrés comme int .

>>> (5).__class__.__name__
'int'
>>> type(5).__name__
'int'

46 votes

C'est d'une simplicité déconcertante. Je me demande pourquoi dir(x.__class__) ne le mentionne pas ?

46 votes

Pourquoi utiliser __class__ sur le type méthode ? Par exemple : type(x).__name__ . N'est-il pas déconseillé d'appeler directement les membres à double soulignement ? Je ne vois pas de moyen de contourner l'utilisation de __name__ Cependant, il ne s'agit pas d'une simple question d'argent, mais bien d'une question de sécurité.

26 votes

Vous devez utiliser __class__ directement pour être compatible avec les classes de l'ancien style, puisque leur type est simplement instance .

483voto

truppo Points 10346

Voulez-vous le nom de la classe sous forme de chaîne de caractères ?

instance.__class__.__name__

8 votes

Ou instance.__class__ pour obtenir l'objet de la classe :D

8 votes

Est-il prudent d'utiliser des propriétés à double trait de soulignement ?

5 votes

@EduardLuca pourquoi ne serait-il pas sûr ? Les propriétés intégrées utilisent des underscores afin de ne pas causer de conflit avec le code que vous écrivez.

132voto

GHZ Points 936

type() ?

>>> class A(object):
...    def whoami(self):
...       print type(self).__name__
...
>>>
>>> class B(A):
...    pass
...
>>>
>>>
>>> o = B()
>>> o.whoami()
'B'
>>>

1 votes

C'est la même chose que la classe mais je dois analyser ce résultat à la main, ce qui est un peu ennuyeux...

10 votes

J'aime bien celle-ci. De cette façon, il est possible dans une classe de base d'obtenir le nom de la sous-classe.

9 votes

O self.__class__.__name__ au lieu de type(self).__name__ pour obtenir le même comportement. À moins qu'il n'y ait quelque chose que le type() La fonction de l'entreprise fait que je ne suis pas au courant de son existence ?

47voto

Jonathan Points 11
class A:
  pass

a = A()
str(a.__class__)

L'exemple de code ci-dessus (lorsqu'il est entré dans l'interpréteur interactif) produira '__main__.A' à l'opposé de 'A' qui est produit si le __name__ est invoqué. En passant simplement le résultat de A.__class__ à la str le parsing est géré pour vous. Cependant, vous pouvez aussi utiliser le code suivant si vous voulez quelque chose de plus explicite.

"{0}.{1}".format(a.__class__.__module__,a.__class__.__name__)

Ce comportement peut être préférable si vous avez des classes avec le même nom définies dans des modules séparés.

L'exemple de code fourni ci-dessus a été testé dans Python 2.7.5.

28voto

Prasath Points 93
type(instance).__name__ != instance.__class__.__name  #if class A is defined like
class A():
   ...

type(instance) == instance.__class__                  #if class A is defined like
class A(object):
  ...

Exemple :

>>> class aclass(object):
...   pass
...
>>> a = aclass()
>>> type(a)
<class '__main__.aclass'>
>>> a.__class__
<class '__main__.aclass'>
>>>
>>> type(a).__name__
'aclass'
>>>
>>> a.__class__.__name__
'aclass'
>>>

>>> class bclass():
...   pass
...
>>> b = bclass()
>>>
>>> type(b)
<type 'instance'>
>>> b.__class__
<class __main__.bclass at 0xb765047c>
>>> type(b).__name__
'instance'
>>>
>>> b.__class__.__name__
'bclass'
>>>

6 votes

Cela n'est vrai que pour l'ancien Python 2.x. En 3.x, bclass() se résoudrait en bclass(object). Et même dans ce cas, de nouvelles classes sont apparues dans Python 2.2.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X