Aunque la respuesta aceptada es acertada, me gustaría agregar una pequeña descripción.
Hagamos un pequeño ejercicio.
En primer lugar, defina una clase de la siguiente manera:
class A:
temp = 'Skyharbor'
def __init__(self, x):
self.x = x
def change(self, y):
self.temp = y
entonces que tenemos aqui?
- Tenemos una clase muy simple que tiene un atributo
tempque es una cadena
- Un
__init__método que estableceself.x
- Un método de cambio establece
self.temp
Bastante sencillo hasta ahora, ¿sí? Ahora comencemos a jugar con esta clase. Inicialicemos esta clase primero:
a = A('Tesseract')
Ahora haga lo siguiente:
>>> print(a.temp)
Skyharbor
>>> print(A.temp)
Skyharbor
Bueno, a.tempfuncionó como se esperaba, pero ¿cómo demonios A.tempfuncionó? Bueno, funcionó porque temp es un atributo de clase. Todo en Python es un objeto. Aquí A es también un objeto de clase type. Por lo tanto, el atributo temp es un atributo mantenido por la Aclase y si cambia el valor de temp a través de A(y no a través de una instancia de a), el valor cambiado se reflejará en toda la instancia de Aclase. Avancemos y hagamos eso:
>>> A.temp = 'Monuments'
>>> print(A.temp)
Monuments
>>> print(a.temp)
Monuments
¿Interesante no? Y tenga en cuenta que id(a.temp)y id(A.temp)siguen siendo los mismos .
Cualquier objeto de Python recibe automáticamente un __dict__atributo, que contiene su lista de atributos. Investiguemos qué contiene este diccionario para nuestros objetos de ejemplo:
>>> print(A.__dict__)
{
'change': <function change at 0x7f5e26fee6e0>,
'__module__': '__main__',
'__init__': <function __init__ at 0x7f5e26fee668>,
'temp': 'Monuments',
'__doc__': None
}
>>> print(a.__dict__)
{x: 'Tesseract'}
Tenga en cuenta que el tempatributo se enumera entre Alos atributos de la clase mientras que xse enumera para la instancia.
Entonces, ¿cómo es que obtenemos un valor definido de a.tempsi ni siquiera está listado para la instancia a? Bueno, esa es la magia del __getattribute__()método. En Python, la sintaxis punteada invoca automáticamente este método, por lo que cuando escribimos a.temp, Python se ejecuta a.__getattribute__('temp'). Ese método realiza la acción de búsqueda de atributos, es decir, encuentra el valor del atributo buscando en diferentes lugares.
La implementación estándar de __getattribute__()búsquedas primero el diccionario interno ( dict ) de un objeto, luego el tipo del objeto en sí. En este caso se a.__getattribute__('temp')ejecuta primero a.__dict__['temp']y luegoa.__class__.__dict__['temp']
Bien, ahora usemos nuestro changemétodo:
>>> a.change('Intervals')
>>> print(a.temp)
Intervals
>>> print(A.temp)
Monuments
Bueno, ahora que lo hemos usado self, print(a.temp)nos da un valor diferente de print(A.temp).
Ahora, si comparamos id(a.temp)y id(A.temp), serán diferentes.
listcomo nombre de atributo.listes una función integrada para construir una nueva lista. Deberías escribir clases de nombres con mayúscula.