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
temp
bę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.temp
działało zgodnie z oczekiwaniami, ale jak do diabła A.temp
dział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 A
klasę i jeśli zmienisz wartość temp za pośrednictwem A
(a nie przez instancję a
), zmieniona wartość zostanie odzwierciedlona we wszystkich instancjach A
klasy. 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 temp
atrybut jest wymieniony wśród A
atrybutów klasy, podczas gdy x
jest wymieniony dla instancji.
Więc jak to się dzieje, że otrzymujemy określoną wartość, a.temp
jeś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 change
metody:
>>> 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.
list
jako nazwy atrybutu.list
jest funkcją wbudowaną do tworzenia nowej listy. Nazwy klas należy pisać dużymi literami.