2012-04-30 15 views
48

me pregunto si hay una diferencia entrePython: self .__ tipo class__ vs (auto)

class Test(object): 
    def __init__(self): 
     print self.__class__.__name__ 

y

class Test(object): 
    def __init__(self): 
     print type(self).__name__ 

?

¿Hay alguna razón para preferir una u otra?

(En mi caso de uso que lo quieren usar para determinar el nombre del registrador, pero creo que esto no importa)

+5

posible duplicado de [Diferencia entre tipo (obj) y obj. \ _ \ _ Clase \ _ \ _] (http://stackoverflow.com/questions/1060499/difference-between-typeobj-and-obj-class) – user

+0

@ usuario y existe una diferencia entre ellos en Python 3 bajo ciertas circunstancias (ver [respuesta] de Flavien (http://stackoverflow.com/a/10633356/704244)) –

Respuesta

31
>>> class Test(object): pass 
>>> t = Test() 
>>> type(t) is t.__class__ 
True 
>>> type(t) 
__main__.Test 

Así que esos dos son lo mismo. Usaría self.__class__ ya que es más obvio de lo que se trata.

Sin embargo, type(t) no funcionará para las clases de estilo antiguo ya que el tipo de una instancia de una clase de estilo antiguo es instance mientras que el tipo de una instancia de clase de nuevo estilo es su clase:

>>> class Test(): pass 
>>> t = Test() 
>>> type(t) is t.__class__ 
False 
>>> type(t) 
instance 
+9

¿De verdad? ¿Tendría acceso a 'self .__ class__' sobre' type (self) '? Creo que este último es más claro, menos tipeo y más consistente. Dudo que harías '[1, 2, 3] .__ len __()' sobre 'len ([1, 2, 3])'. –

+9

Bueno 'len()' te dice lo que hace, pero 'tipo (self)' no te dice inmediatamente "te da la clase" – ThiefMaster

+5

Las versiones anteriores de Python, Type y Class también están en Python, así que supongo Realmente no lo veo así. –

4

Por lo que yo sé, este último es sólo una manera más agradable de hacer el ex.

En realidad no es tan inusual en Python, considere repr(x), que sólo llama x.__repr__() o len(x), que acaba de llamadas x.__len__(). Python prefiere usar integradas para funciones comunes que probablemente utilizará en un rango de clases, y generalmente las implementa llamando a los métodos __x__().