2012-01-29 10 views
142

Duplicar posibles:
Variables inside and outside of a class __init__() functionforma correcta para definir las variables de clase en Python

me di cuenta de que en Python, las personas inicializar los atributos de su clase de dos maneras diferentes.

La primera forma es la siguiente:

class MyClass: 
    __element1 = 123 
    __element2 = "this is Africa" 

    def __init__(self): 
    #pass or something else 

El otro estilo se parece a:

class MyClass: 
    def __init__(self): 
    self.__element1 = 123 
    self.__element2 = "this is Africa" 

¿Cuál es la forma correcta para inicializar atributos de clase?

+3

la difrencia no es grande si usa cadenas ... pero obtendrá una cosa completamente diferente si usa dictados o listas que están almacenadas por referencia – Bastian

Respuesta

355

Ambos caminos no son correctas o incorrectas, que son sólo dos diferentes tipos de elementos de la clase:

  • elementos fuera del método __init__ son elementos estáticos, es decir, que pertenecen a la clase. Los elementos del __init__ son elementos del objeto (self), no pertenecen a la clase.

Lo verá más claramente con algo de código:

class MyClass: 
    static_elem = 123 

    def __init__(self): 
     self.object_elem = 456 

c1 = MyClass() 
c2 = MyClass() 

# Initial values of both elements 
>>> print c1.static_elem, c1.object_elem 
123 456 
>>> print c2.static_elem, c2.object_elem 
123 456 

# Nothing new so far ... 

# Let's try changing the static element 
MyClass.static_elem = 999 

>>> print c1.static_elem, c1.object_elem 
999 456 
>>> print c2.static_elem, c2.object_elem 
999 456 

# Now, let's try changing the object element 
c1.object_elem = 888 

>>> print c1.static_elem, c1.object_elem 
999 888 
>>> print c2.static_elem, c2.object_elem 
999 456 

Como se puede ver, cuando cambiamos el elemento de clase, que cambió para ambos objetos. Pero, cuando cambiamos el elemento objeto, el otro objeto permaneció sin cambios.

+2

pero siendo __init__ siempre ejecutado después de que se crea el objeto, se vuelve prácticamente igual para definir variables fuera de __init__, ¿verdad? – jeanc

+0

la gran diferencia es que los elementos estáticos pertenecen a la clase, no al objeto. Editaré mi respuesta con un poco más de explicación. – juliomalegria

+2

Si cambia un atributo de clase (uno definido fuera de '__init __()') cambia para toda la clase. También cambiará para otras instancias, mientras que los atributos de instancia (definidos en '__init __()') son específicos de cada instancia. – nitsas

7

creo que esta muestra explica la diferencia entre los estilos:

[email protected]:~$cat test.py 
#!/usr/bin/env python 

class MyClass: 
    element1 = "Hello" 

    def __init__(self): 
     self.element2 = "World" 

obj = MyClass() 

print dir(MyClass) 
print "--" 
print dir(obj) 
print "--" 
print obj.element1 
print obj.element2 
print MyClass.element1 + " " + MyClass.element2 
[email protected]:~$./test.py 
['__doc__', '__init__', '__module__', 'element1'] 
-- 
['__doc__', '__init__', '__module__', 'element1', 'element2'] 
-- 
Hello World 
Hello 
Traceback (most recent call last): 
    File "./test.py", line 17, in <module> 
    print MyClass.element2 
AttributeError: class MyClass has no attribute 'element2' 

element1 está ligada a la clase, elemento2 está obligado a una instancia de la clase.

+0

gracias por su respuesta – jeanc

+3

Su última declaración no es correcta; el objeto no obtiene una * copia * de las variables de clase. Todas las instancias de una clase comparten acceso a las mismas variables de clase. – Ben

+1

@Ben Tienes razón; He eliminado esa oración. –

Cuestiones relacionadas