Незважаючи на те, що прийнята анвер пляма, я хочу додати трохи опису.
Давайте зробимо невелику вправу
насамперед визначте клас наступним чином:
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- це вбудована функція для створення нового списку. Ви повинні написати класи імен з великої літери.