W Pythonie 2, typ i klasa nie to samo, w szczególności, na zajęcia w starym stylu, type(obj)
is not the same object jako obj.__class__
. Więc to jest możliwe, ponieważ instancje klas starym stylu są rzeczywiście innego typu (instance
) niż ich klasy:
>>> class A(): pass
>>> class B(A): pass
>>> b = B()
>>> assert b.__class__ is B
>>> issubclass(b.__class__, A) # same as issubclass(B, A)
True
>>> issubclass(type(b), A)
False
>>> type(b)
<type 'instance'>
>>> b.__class__
<class __main__.B at 0x10043aa10>
ten został rozwiązany w klasach w nowym stylu:
>>> class NA(object): pass
>>> class NB(NA): pass
>>> nb = NB()
>>> issubclass(type(nb), NA)
True
>>> type(nb)
<class '__main__.NB'>
>>> nb.__class__
<class '__main__.NB'>
starym stylu Klasa nie jest typem, klasa nowego stylu to:
>>> isinstance(A, type)
False
>>> isinstance(NA, type)
True
Stare klasy stylów są uznawane za przestarzałe. W Pythonie 3 istnieją tylko klasy w nowym stylu; class A()
jest odpowiednikiem class A(object)
, a Twój kod przyniesie True
w obu kontrolach.
Spójrz na to pytanie na trochę więcej dyskusji: What is the difference between old style and new style classes in Python?
+1: To bardzo jasny opis i bardzo dobry punkt. Dzięki! – EOL
Dla każdego, kto się zastanawia, 'isinstance' jest [specjalny-cased] (https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects/abstract.c#L2898) dla klasycznych wystąpień i klas (np.' PyClass_Check (cls) && PyInstance_Check (inst) 'in C). Ponieważ nie ma zależności typu, otrzymuje on '__class__' instancji dla sprawdzenia' issubclass', który jest również [special-cased] (https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects /classobject.c#L486) dla klas w starym stylu. – eryksun