tutorial lenguaje espaƱol descargar python

lenguaje - python tutorial



Utilidad de def__init__(self)? (3)

Soy bastante nuevo en Python, y noté estas publicaciones: Python __init__ y yo ¿qué hacen ellos? y Python Classes sin usar def __init __ (self)

Sin embargo, después de jugar con él, noté que estas dos clases dan resultados aparentemente equivalentes-

class A(object): def __init__(self): self.x = ''Hello'' def method_a(self, foo): print self.x + '' '' + foo

(de esta pregunta )

y

class B(object): x = ''Hello'' def method_b(self,foo): print self.x + '' '' + foo

¿Hay alguna diferencia real entre estos dos? O, de manera más general, ¿ __init__ cambia algo inherentemente sobre los atributos de una clase? En la documentación se menciona que __init__ se __init__ cuando se crea la instancia. ¿Esto significa que x en la clase B se establece antes de la instanciación?


Como otros han declarado, es la diferencia entre una variable en una clase y una variable en una instancia de clase. Vea el siguiente ejemplo.

>>> class A: ... a = [] ... >>> class B: ... def __init__(self): ... self.b = [] ... >>> a1 = A() >>> a1.a.append(''hello'') >>> a2 = A() >>> a2.a [''hello''] >>> b1 = B() >>> b1.b.append(''goodbye'') >>> b2 = B() >>> b2.b []

Para objetos inmutables como tuplas, cadenas, etc., es más difícil notar la diferencia, pero para las variables mutables, todo cambia: los cambios aplicados se comparten entre TODAS las instancias de esa clase.

Tenga en cuenta también que el mismo comportamiento ocurre para los valores predeterminados de los argumentos de las palabras clave.

>>> class A: ... def __init__(self, a=[]): ... a.append(''hello'') ... print(a) ... >>> A() [''hello''] >>> A() [''hello'', ''hello''] >>> A() [''hello'', ''hello'', ''hello''] >>> class B: ... def __init__(self, b=None): ... if b is None: ... b = [] ... b.append(''goodbye'') ... print(b) ... >>> B() [''goodbye''] >>> B() [''goodbye''] >>> B() [''goodbye'']

Este comportamiento muerde a muchos nuevos programadores de Python. ¡Bien por ti al descubrir estas distinciones desde el principio!


En el primer ejemplo, tienes la variable de la instancia de la clase. Esta variable solo es accesible a través de una instancia (auto requerida).

class A(): def __init__(self): self.x = ''hello'' print A.x -> AttributeError print A().x -> ''hello''

En el segundo ejemplo, tienes una variable estática. Puedes acceder a esta variable gracias al nombre de la clase A

class A(): x = ''hello'' print A.x -> ''hello'' print A().x -> ''hello''

De hecho, puede tener una variable estática y una variable de instancia con el mismo nombre:

class A(): x = ''hello'' def __init__(self): self.x = ''world'' print A.x -> hello print A().x -> world

El valor estático se comparte entre todas las instancias

class A(): x = ''hello'' @staticmethod def talk(): print A.x a = A() print a.talk() -> hello A.x = ''world'' print a.talk() -> world

Tiene un buen artículo aquí: http://linuxwell.com/2011/07/21/static-variables-and-methods-in-python/


Sí, mira esto:

class A(object): def __init__(self): self.lst = [] class B(object): lst = []

y ahora prueba:

>>> x = B() >>> y = B() >>> x.lst.append(1) >>> y.lst.append(2) >>> x.lst [1, 2] >>> x.lst is y.lst True

y esto:

>>> x = A() >>> y = A() >>> x.lst.append(1) >>> y.lst.append(2) >>> x.lst [1] >>> x.lst is y.lst False

¿Esto significa que x en la clase B se establece antes de la instanciación?

Sí, es un atributo de clase (se comparte entre instancias). Mientras que en la clase A es un atributo de instancia. Simplemente sucede que las cadenas son inmutables, por lo tanto, no hay una diferencia real en su escenario (excepto que la clase B usa menos memoria, ya que solo define una cadena para todas las instancias). Pero hay uno enorme en mi ejemplo.