2012-03-14 22 views

risposta

18

In Python 2, tipo e classe non sono la stessa cosa, in particolare, per le classi di vecchio stile, type(obj)is not the same object come obj.__class__. Così è possibile, perché le istanze di classi in stile antico sono in realtà di tipo diverso (instance) che la loro classe:

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

Questo si risolve in classi di nuovo stile:

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

Old-style la classe non è un tipo, la classe new-style è:

>>> isinstance(A, type) 
False 
>>> isinstance(NA, type) 
True 

Le classi di vecchio stile sono dichiarate deprecate. In Python 3, ci sono solo classi di nuovo stile; class A() equivale a class A(object) e il tuo codice produrrà True in entrambi i controlli.

Date un'occhiata a questa domanda per un po 'di discussione: What is the difference between old style and new style classes in Python?

+0

+1: questa è una descrizione molto chiara e un ottimo punto. Grazie! – EOL

+0

Per chiunque si domandi, 'isinstance' è [special-cased] (https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects/abstract.c#L2898) per le istanze e le classi vecchio stile (ad esempio' PyClass_Check (cls) && PyInstance_Check (inst) 'in C). Poiché non esiste una relazione di tipo, ottiene il '__class__' dell'istanza per un controllo' issubclass', che è anche [speciale-cased] (https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects /classobject.c#L486) per le classi vecchio stile. – eryksun

6

Tutto è un oggetto:

isinstance(123, object) # True 
isinstance("green cheese", object) # True 
isinstance(someOldClassObject, object) # True 
isinstance(someNewClassObject, object) # True 
isinstance(object, object) # True 
isinstance(None, object) # True 

presente che questa domanda non ha nulla a che fare essenzialmente con la vecchiaia vs classi di nuovo stile. isinstance(old_style, object) è True è semplicemente un corollario del fatto che ogni valore in python è un'istanza di object.

+0

Hai un riferimento su questo? – EOL

+1

@EOL: [questo qui] (http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html) è piuttosto utile – georg

+1

Grazie. Ho dato un'occhiata al riferimento, ma non riesco a trovare da nessuna parte alcuna indicazione dell'idea che tutto in Python sia di * tipo * 'oggetto' (il fatto che" tutto sia un oggetto "in Python non significhi la stessa cosa). – EOL

1

Quando si esegue l'espressione

old_style = OldStyle() 

Significa che si sta istanziare l'oggetto, che letti, riuscendo così è un'istanza della classe OldStyle.

Inoltre, entrambi valutano True in Python 3.2.

Problemi correlati