Mimo że przyjęta odpowiedź jest trafna, chciałbym nieco dodać opis.
Zróbmy małe ćwiczenie
przede wszystkim zdefiniuj klasę w następujący sposób:
class A:
temp = 'Skyharbor'
def __init__(self, x):
self.x = x
def change(self, y):
self.temp = y
Więc co tu mamy?
- Mamy bardzo prostą klasę, która ma atrybut
tempbędący łańcuchem znaków
__init__Metoda, która ustawiaself.x
- Zestawy metod zmiany
self.temp
Jak dotąd całkiem proste, tak? Teraz zacznijmy bawić się tą klasą. Zainicjujmy najpierw tę klasę:
a = A('Tesseract')
Teraz wykonaj następujące czynności:
>>> print(a.temp)
Skyharbor
>>> print(A.temp)
Skyharbor
Cóż, a.tempdziałało zgodnie z oczekiwaniami, ale jak do diabła A.tempdziałało? Cóż, zadziałało, ponieważ temp jest atrybutem klasy. Wszystko w Pythonie jest obiektem. Tutaj A jest również przedmiotem klasy type. Zatem atrybut temp jest atrybutem utrzymywanym przez Aklasę i jeśli zmienisz wartość temp za pośrednictwem A(a nie przez instancję a), zmieniona wartość zostanie odzwierciedlona we wszystkich instancjach Aklasy. Zróbmy to dalej:
>>> A.temp = 'Monuments'
>>> print(A.temp)
Monuments
>>> print(a.temp)
Monuments
Ciekawe, prawda? I pamiętać, że id(a.temp)i id(A.temp)są wciąż takie same .
Każdy obiekt Pythona automatycznie otrzymuje __dict__atrybut, który zawiera listę atrybutów. Zbadajmy, co zawiera ten słownik dla naszych przykładowych obiektów:
>>> print(A.__dict__)
{
'change': <function change at 0x7f5e26fee6e0>,
'__module__': '__main__',
'__init__': <function __init__ at 0x7f5e26fee668>,
'temp': 'Monuments',
'__doc__': None
}
>>> print(a.__dict__)
{x: 'Tesseract'}
Zauważ, że tempatrybut jest wymieniony wśród Aatrybutów klasy, podczas gdy xjest wymieniony dla instancji.
Więc jak to się dzieje, że otrzymujemy określoną wartość, a.tempjeśli nie ma jej nawet na liście dla instancji a. Na tym polega magia __getattribute__()metody. W Pythonie kropkowana składnia automatycznie wywołuje tę metodę, więc kiedy piszemy a.temp, Python wykonuje a.__getattribute__('temp'). Ta metoda wykonuje akcję wyszukiwania atrybutu, tj. Znajduje wartość atrybutu, patrząc w różnych miejscach.
Standardowa implementacja __getattribute__()przeszukuje najpierw wewnętrzny słownik ( dict ) obiektu, a następnie typ samego obiektu. W tym przypadku a.__getattribute__('temp')wykonuje najpierw, a.__dict__['temp']a potema.__class__.__dict__['temp']
Okej, teraz użyjmy naszej changemetody:
>>> a.change('Intervals')
>>> print(a.temp)
Intervals
>>> print(A.temp)
Monuments
Teraz, gdy już użyliśmy self, print(a.temp)daje nam inną wartość z print(A.temp).
Teraz, jeśli porównamy id(a.temp)i id(A.temp), będą one różne.
listjako nazwy atrybutu.listjest funkcją wbudowaną do tworzenia nowej listy. Nazwy klas należy pisać dużymi literami.