Python - atrybut instancji, atrybut klasy

Napisano: 18 listopada 2010 23:38
Tagi: python

Python jest dziwnym językiem, językiem silnie zależnym od konwencji. Chociaż wiedziałem, że dużo w tym języku zależy od konwencji, mocno mnie zaskoczyło to, jak bardzo konwencja wpływa na programy w pythonie. Bloki kodu wydzielone poprzez wcięcia to banał.

Poruszyło mnie dość mocno jedna rzecz, deklaracja atrybutów klasy. Zanim zacząłem pisać pierwszy program w pythonie, trochę poczytałem, więc mniej więcej wiedziałem, że tworząc klasę, można mieć atrybuty klasy (statyczne), jak i instancji, do których odwołać można się w następujący sposób:

Python code
  1. class Klasa(object):
  2.  
  3.         def __init__(self):
  4.                 self.someMethod()
  5.  
  6.         def someMethod(self):
  7.                 //atrybut instancji
  8.                 self.atrybut
  9.                 //atrybut klasy
  10.                 self.__class__.atrybut

Oczywiście, nie ma żadnego słowa kluczowego, który by zasugerował, że atrybut jest taki, lub taki. Ja, jak to mam w zwyczaju, atrybuty deklaruję zawsze w klasie, a następnie do nich się odwołuję:

Python code
  1. class Klasa(object):
  2.         atrybut = []
  3.  
  4.         def __init__(self):
  5.                 self.someMethod()
  6.  
  7.         def someMethod(self):
  8.                 //atrybut instancji
  9.                 self.atrybut
  10.                 //atrybut klasy
  11.                 self.__class__.atrybut

Z takim podejściem jest jeden kłopot. Załóżmy teraz takie odwołanie do atrybutu w metodzie:

Python code
  1. class Klasa(object):
  2.         atrybut = []
  3.  
  4.         def __init__(self):
  5.                 self.someMethod()
  6.  
  7.         def someMethod(self):
  8.                 //atrybut instancji (?)
  9.                 self.atrybut.append('string')

Python ma dość nietypowe podejście do atrybutów klasy (statycznych). Po pierwsze, deklaracja atrybutów w ciele klasy jest przede wszystkim statyczna - atrybuty klasy. I moje przyzwyczajenie nie wydaje się być złe. Pozwala na deklarację jakichś wartości domyślnych dla obiektów. Co się natomiast dzieje w metodzie someMethod? Wszelkie przewodniki twierdzą, że jest to odwołanie do atrybutu klasy, jednak w tym wypadku, Łańcuch znaków 'string' zostaje dodany do atrybutu statycznego. Dlaczego, w końcu odwołujemy się teoretycznie do atrybutu instancji?

Jak się okazuje, atrybuty klas w pythonie działają na zasadzie słowników (coś jak tablica w php, posiada klucze i wartości). W momencie, gdy atrybutu nie ma w słowniku instancji, jest szukany w słowniku klasy, a jeśli tam go nie ma, w słowniku klasy, którą nasza rozszerza. W powyższym przykładzie zadeklarowany jest atrybut klasy, a w metodzie someMethod, odwołanie zostaje skierowane do atrybutu klasy właśnie. Jak więc dodać atrybut do słownika trybutów instancji? Tylko poprzez wcześniejszą inicjację atrybutu:

Python code
  1. class Klasa(object):
  2.         atrybut = []
  3.  
  4.         def __init__(self):
  5.                 // odwołanie do atrybutu klasy
  6.                 self.someMethod()
  7.                 // inicjacja atrybutu instancji
  8.                 self.atrybut = []
  9.                 // odwołanie do atrybutu instancji
  10.                 self.someMethod()
  11.  
  12.         def someMethod(self):
  13.                 //atrybut instancji (?)
  14.                 self.atrybut.append('string')

Zanim się w tym zorientowałem, doprowadziłem do małego wycieku pamięci ;-).

Więcej do poczytania (po angielsku) na ten temat można znaleźć w tych linkach:

http://www.pasteur.fr/formation/infobio/python/ch18s05.html
http://docs.python.org/tutorial/classes.html#python-scopes-and-namespaces

Grzegorz Śliwiński

Skomentuj pierwszy!

Skomentuj!

Adres email nie zostanie opublikowany

Musi zaczynać się od http:// lub https://
Usuń odpowiedź