Zanurkuj w Pythonie/Atrybuty klas
Atrybuty klas
edytujWiemy już, co to są atrybuty, które są częścią konkretnych obiektów. W Pythonie możemy tworzyć też atrybuty klas, czyli zmienne należące do samej klasy (a nie do instancji tej klasy).
Przykład. Atrybuty klas
class MP3FileInfo(FileInfo): u"przechowuje znaczniki ID3v1.0 MP3" tagDataMap = {u"tytuł" : ( 3, 33, stripnulls), "artysta" : ( 33, 63, stripnulls), "album" : ( 63, 93, stripnulls), "rok" : ( 93, 97, stripnulls), "komentarz" : ( 97, 126, stripnulls), "gatunek" : (127, 128, ord)} >>> import fileinfo >>> fileinfo.MP3FileInfo #(1) <class 'fileinfo.MP3FileInfo'> >>> fileinfo.MP3FileInfo.tagDataMap #(2) {'album': (63, 93, <function stripnulls at 0xb7c000d4>), 'rok': (93, 97, <function stripnulls at 0xb7c000d4>), 'komentarz': (97, 126, <function stripnulls at 0xb7c000d4>), u'tytu\u0142': (3, 33, <function stripnulls at 0xb7c000d4>), 'artysta': (33, 63, <function stripnulls at 0xb7c000d4>), 'gatunek': (127, 128, <built-in function ord>)} >>> m = fileinfo.MP3FileInfo() #(3) >>> m.tagDataMap {'album': (63, 93, <function stripnulls at 0xb7c000d4>), 'rok': (93, 97, <function stripnulls at 0xb7c000d4>), 'komentarz': (97, 126, <function stripnulls at 0xb7c000d4>), u'tytu\u0142': (3, 33, <function stripnulls at 0xb7c000d4>), 'artysta': (33, 63, <function stripnulls at 0xb7c000d4>), 'gatunek': (127, 128, <built-in function ord>)}
MP3FileInfo
jest klasą, nie jest instancją klasy.tagDataMap
jest atrybutem klasy i jest dostępny już przed stworzeniem jakiegokolwiek obiektu danej klasy.- Atrybuty klas są dostępne na dwa sposoby: poprzez bezpośrednie odwołanie do klasy lub poprzez jakąkolwiek instancję tej klasy.
W Javie zarówno zmienne statyczne (w Pythonie zwane atrybutami klas), jak i zmienne obiektów (w Pythonie zwane atrybuty lub atrybutami instancji) są definiowane bezpośrednio za definicją klasy (jedne ze słowem kluczowym static , a inne bez niego). W Pythonie tylko atrybuty klas są definiowane bezpośrednio po definicji klasy. Atrybuty instancji definiujemy w metodzie __init__ .
|
Atrybuty klas mogą być używane jako stałe tych klas (w takim celu korzystamy z nich w klasie MP3FileInfo
), ale tak naprawdę nie są stałe. Można je zmieniać.
W Pythonie nie istnieją stałe. Wszystko możemy zmienić, jeśli tylko odpowiednio się postaramy. To efekt jednej z podstawowych zasad Pythona: powinno się zniechęcać do złego działania, ale nie zabraniać go. Jeśli naprawdę chcesz zmienić wartość None , możesz to zrobić, ale nie przychodź z płaczem, kiedy twój kod stanie się niemożliwy do debugowania.
|
Przykład. Modyfikowanie atrybutów klas
>>> class counter(object): ... count = 0 #(1) ... def __init__(self): ... self.__class__.count += 1 #(2) ... >>> counter <class __main__.counter> >>> counter.count #(3) 0 >>> c = counter() >>> c.count #(4) 1 >>> counter.count 1 >>> d = counter() #(5) >>> d.count 2 >>> c.count 2 >>> counter.count 2
count
jest atrybutem klasycounter
.__class__
jest wbudowanym atrybutem każdego obiektu. Jest to referencja do klasy, której obiektem jestself
(w tym wypadku do klasycounter
).- Ponieważ
count
jest atrybutem klasy, jest dostępny poprzez bezpośrednie odwołanie do klasy, przed stworzeniem jakiegokolwiek obiektu. - Kiedy tworzymy instancję tej klasy, automatycznie zostanie wykonana metoda
__init__
, która zwiększa atrybut tej klasy o nazwiecount
o1
. Operacja ta wpływa na klasę samą w sobie, a nie tylko na dopiero co stworzony obiekt. - Stworzenie drugiego obiektu ponownie zwiększy atrybut
count
. Zauważmy, że atrybuty klas są wspólne dla klasy i wszystkich jej instancji.