2010-12-18 27 views
14

Estoy un poco confundido acerca de los tipos y clases en Python. Por ej. la siguiente conversación REPL me confunde:Tipos y clases en Python

>>> class A: pass 
... 
>>> a = A() 
>>> type(a) 
<type 'instance'> 
>>> a.__class__ 
<class __main__.A at 0xb770756c> 
>>> type([]) 
<type 'list'> 
>>> [].__class__ 
<type 'list'> 
>>> type(list) 
<type 'type'> 
>>> list.__class__ 
<type 'type'> 
>>> type(A) 
<type 'classobj'> 
>>> A.__class__ 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: class A has no attribute '__class__' 
  1. ¿Por qué el tipo y la clase de cosas incorporadas (por ejemplo, la lista aquí) lo mismo pero diferente para el usuario clases/tipos?
  2. ¿No es cada clase una instancia de alguna otra clase (como Clase en Java)? ¿Por qué no __class__ para las clases definidas por el usuario?

Cualquier explicación/lectura adicional que pueda aclarar este comportamiento sería muy apreciada. TIA.

+4

Debe definir sus clases con 'clase A (objeto)'. Entonces obtendrás '' para 'type (a)'. –

Respuesta

13

Encontrará el comportamiento diferente para las nuevas clases de estilo frente a las clases clásicas. Para leer más, lea esto: Python Data Model. Lea específicamente la sección sobre clases y la diferencia entre el nuevo estilo y las clases clásicas.

intente escribir lo siguiente en su REPL:

class A: pass 
class B(object): pass 

y verá que se obtienen diferentes resultados. Aquí está lidiando con la diferencia entre el estilo nuevo y las clases de estilo antiguo. Usando Python 2.6.1 esto es lo que obtengo:

> type(A) 
<type "classobj"> 
> type(B) 
<type "type"> 

que indica que las listas son nuevas clases de estilo y no antiguas. Podemos jugar más en todo con las cosas usando list así:

> type(list) 
<type "type"> 

mismo que nuestro resultado class B(object): pass. Y también

> c = [] 
> type(c) 
<type "list"> 

que le informa sobre la instancia del objeto y no su definición.

+0

Parece que mi error fue no usar nuevas clases de tipos que terminaron dándome resultados extraños (seguramente por compatibilidad con versiones anteriores). El enlace parece interesante. Gracias. – sasuke

4

Es "razones de Hystorical". O posible "Histerical". Todo está fijado en Python 3:

>>> class A: pass 
... 
>>> a = A() 
>>> type(a) 
<class '__main__.A'> 
>>> a.__class__ 
<class '__main__.A'> 
>>> type([]) 
<class 'list'> 
>>> [].__class__ 
<class 'list'> 
>>> type(list) 
<class 'type'> 
>>> list.__class__ 
<class 'type'> 
>>> type(A) 
<class 'type'> 
>>> A.__class__ 
<class 'type'> 
>>> class B(object): pass 
... 
>>> type(B) 
<class 'type'> 
>>> b = B() 
>>> type(b) 
<class '__main__.B'> 
+0

Eso es bueno saberlo. No me di cuenta de que Python 3 había arreglado el problema todos juntos. Supongo, entonces, que todas las clases independientemente de derivar explícitamente de 'objeto' derivan de' objeto' ¿entonces? – wheaties

+0

Eso se entiende correctamente. –

1

En Python 3.0, objetos de clase definidos por el usuario son instancias del tipo llamado objeto, que es en sí una clase. • En Python 2.6, las clases de nuevo estilo heredan de un objeto, que es una subclase de tipo; • las clases clásicas son instancias de tipo y no se crean a partir de una clase.