2012-03-14 20 views

Respuesta

18

En Python 2, tipo y clase no son la misma cosa, en concreto, para las clases de estilo antiguo, type(obj)is not the same object como obj.__class__. Por lo que es posible debido a que las instancias de clases de estilo antiguo en realidad son de un tipo diferente (instance) de su clase:

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

Esto se resuelve en las clases de nuevo estilo:

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

-viejo estilo clase no es un tipo, la clase de nuevo estilo es:

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

Las clases de estilo antiguo se declaran obsoletas. En Python 3, solo hay clases de estilo nuevo; class A() es equivalente a class A(object) y su código arrojará True en ambos controles.

Echa un vistazo a esta pregunta para algunos más discusión: What is the difference between old style and new style classes in Python?

+0

+1: Esta es una descripción muy clara, y un muy buen punto. ¡Gracias! – EOL

+0

Para cualquier persona que se pregunte, 'isinstance' es [special-cased] (https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects/abstract.c#L2898) para instancias y clases antiguas (es decir,' PyClass_Check (cls) && PyInstance_Check (inst) 'en C). Como no hay una relación basada en tipo, obtiene el '__class__' de la instancia para una comprobación' issubclass', que también es [special-cased] (https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects /classobject.c#L486) para clases antiguas. – eryksun

6

Todo es un objeto:

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 

Tenga en cuenta que esta pregunta no tiene prácticamente nada que ver con la edad- frente a las clases de nuevo estilo. isinstance(old_style, object) siendo True es simplemente un corolario del hecho de que cada valor en python es una instancia de object.

+0

¿Tiene una referencia al respecto? – EOL

+1

@EOL: [este] (http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html) es bastante útil – georg

+1

Gracias. He echado un vistazo a la referencia, pero no puedo encontrar en ninguna parte la idea de que todo en Python sea de * tipo * 'objeto' (el hecho de que" todo es un objeto "en Python no significa lo mismo) – EOL

1

Al hacer la expresión

old_style = OldStyle() 

Esto significa que son una instancia del objeto, que old_style es una instancia de la clase OldStyle.

Además, ambos evalúan a True en Python 3.2.

Cuestiones relacionadas