Хотя принятый ответ находится на месте, я хотел бы добавить немного описания.
Давайте сделаем небольшое упражнение
Прежде всего определите класс следующим образом:
class A:
temp = 'Skyharbor'
def __init__(self, x):
self.x = x
def change(self, y):
self.temp = y
Так что у нас здесь?
- У нас есть очень простой класс, который имеет атрибут
temp
который является строкой
__init__
Метод , который устанавливаетself.x
- Набор методов изменения
self.temp
Довольно прямо вперед, да? Теперь давайте начнем играть с этим классом. Давайте сначала инициализируем этот класс:
a = A('Tesseract')
Теперь сделайте следующее:
>>> print(a.temp)
Skyharbor
>>> print(A.temp)
Skyharbor
Ну, a.temp
работал, как ожидалось, но как, черт возьми, A.temp
работал? Ну, это сработало, потому что temp является атрибутом класса. Все в питоне является объектом. Здесь А также является объектом класса type
. Таким образом, атрибут temp является атрибутом, хранящимся в A
классе, и если вы измените значение temp через A
(а не через экземпляр a
), измененное значение будет отражено во всех экземплярахA
класса. Давайте продолжим и сделаем это:
>>> A.temp = 'Monuments'
>>> print(A.temp)
Monuments
>>> print(a.temp)
Monuments
Интересно не так ли? И обратите внимание, что id(a.temp)
иid(A.temp)
все те же .
Любой объект Python автоматически получает __dict__
атрибут, который содержит его список атрибутов. Давайте исследуем, что этот словарь содержит для наших примеров объектов:
>>> print(A.__dict__)
{
'change': <function change at 0x7f5e26fee6e0>,
'__module__': '__main__',
'__init__': <function __init__ at 0x7f5e26fee668>,
'temp': 'Monuments',
'__doc__': None
}
>>> print(a.__dict__)
{x: 'Tesseract'}
Обратите внимание, что temp
атрибут указан средиA
атрибутов класса, а x
для экземпляра.
Так почему же мы получаем определенное значение, a.temp
если оно даже не указано для экземпляра a
? Ну, это магия __getattribute__()
метода. В Python пунктирный синтаксис автоматически вызывает этот метод, поэтому, когда мы пишемa.temp
, Python выполняетa.__getattribute__('temp')
. Этот метод выполняет действие поиска атрибута, то есть находит значение атрибута, просматривая разные места.
Стандартная реализация __getattribute__()
ищет сначала внутренний словарь ( dict ) объекта, а затем тип самого объекта. В этом случае a.__getattribute__('temp')
выполняется первымa.__dict__['temp']
а затемa.__class__.__dict__['temp']
Хорошо, теперь давайте использовать наш change
метод:
>>> a.change('Intervals')
>>> print(a.temp)
Intervals
>>> print(A.temp)
Monuments
Ну, теперь, когда мы использовали self
, print(a.temp)
дает нам другое значение print(A.temp)
.
Теперь, если мы сравним id(a.temp)
и id(A.temp)
, они будут другими.
list
в качестве имени атрибута.list
является встроенной функцией для создания нового списка Вы должны написать имя классов с заглавной буквы.