Question

Quelle est la différence entre et type(obj) obj.__class__? Y at-il jamais possible de type(obj) is not obj.__class__?

Je veux écrire une fonction qui fonctionne de manière générique sur les objets fournis, en utilisant une valeur par défaut de 1 dans le même type comme un autre paramètre. Quelle variation, # 1 ou 2 ci-dessous, va faire la bonne chose?

def f(a, b=None):
  if b is None:
    b = type(a)(1) # #1
    b = a.__class__(1) # #2
Était-ce utile?

La solution

type(obj) et ne se comportent pas type.__class__ même pour les classes de style ancien:

>>> class a(object):
...     pass
...
>>> class b(a):
...     pass
...
>>> class c:
...     pass
...
>>> ai=a()
>>> bi=b()
>>> ci=c()
>>> type(ai) is ai.__class__
True
>>> type(bi) is bi.__class__
True
>>> type(ci) is ci.__class__
False

Autres conseils

Ceci est une vieille question, mais aucune des réponses semble mentionner. dans le cas général, il est possible pour une nouvelle classe de style pour avoir des valeurs différentes pour et type(instance) instance.__class__:

class ClassA(object):
    def display(self):
        print("ClassA")

class ClassB(object):
    __class__ = ClassA

    def display(self):
        print("ClassB")

instance = ClassB()

print(type(instance))
print(instance.__class__)
instance.display()

Sortie:

<class '__main__.ClassB'>
<class '__main__.ClassA'>
ClassB

La raison est que le remplaçant est ClassB descripteur __class__, mais le champ de type interne dans l'objet ne change pas. <=> lit directement de ce champ de type, de sorte qu'il renvoie la valeur correcte, alors que <=> se réfère au nouveau descripteur remplaçant le descripteur original fourni par python, qui lit le champ de type interne. Au lieu de lire ce champ de type interne, il renvoie une valeur hardcoded.

Classes de style ancien sont le problème, en soupirant:

>>> class old: pass
... 
>>> x=old()
>>> type(x)
<type 'instance'>
>>> x.__class__
<class __main__.old at 0x6a150>
>>> 

Pas un problème en Python 3 puisque toutes les classes sont nouveau style maintenant, -.)

En Python 2, une classe est nouveau style que si elle hérite d'une autre classe nouveau style (y compris et les différents object types intégrés tels que dict, list, set,. ..) ou définit implicitement ou explicitement à __metaclass__ type.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top