Strona główna Polish Python Coders Group
   Strona główna   Pomoc Zaloguj się Rejestracja  
Witamy, Gość. Zaloguj się lub zarejestruj.
Czy dotarł do Ciebie email aktywacyjny?

Zaloguj się podając nazwę użytkownika, hasło i długość sesji

Aktualności:
Szukaj Szukaj
Strony: [1]   Do dołu
Drukuj
Wątek: Prośba o pomoc w zrozumieniu atrybutów klas oraz ich instancji  (Przeczytany 10188 razy)
« : 14:56 23/08/11 »
sebatbg Offline
Hello World!

Zobacz profil
*

Reputacja: -1
Wiadomości: 24


Witam

Jakiś czas temu zacząłem się uczyć klas w pythonie, i po długiej i żmudnej nauce umiem już kawałek...

Niestety napotkałem na zagadnienie którego nie potrafię przeskoczyć...

Wydrukowałem sobie nawet temat przyklejony dotyczący metod i atrybutów klas autorstwa zuo i czytałem go już kilkanaście razy i wciąż mi się plącze...

Chodzi o drugi punkt - Atrybuty...

Pierwsze zdanie od razu powaliło mnie na kolana...

Cytuj
W Pythonie do prawie każdego obiektu - w tym również do obiektów klas oraz obiektów ich instancji - możemy dodawać atrybuty (czyli zmienne składowe) dowolnych typów:

Z tego co zrozumiałem chodzi o to, że wiem że atrybuty klasy wypisuje się  w linijkach między class i nazwą klasy a definicją metody...
Potem mogę się do tego odwoływać poprzez:
class jajco:
         jajo = 5

print jajco.jajo

Z obiektami klasy (czyli instancjami) też łapię...

Natomiast dalej to już leżę...-"oraz obiektów ich instancji"...

Czyli chodzi o to, że instancje też mają własne obiekty?
Hmmm...może to są te zmienne(atrybuty?) które np tworzy __init__ albo można sobie stworzyć w jakieś metodzie?
Wiem(chyba), że w momencie gdy w definicji metody na początku znajduje się parametr self to metoda dotyczy właśnie instancji klasy...więc może wszystkie zmienne w metodzie są właśnie atrybutami instancji?

Szkoda, że zuo nie podał pełnego przykładowego kodu z komentarzami co jest czym...

Jeżeli ktoś może to prosiłbym o napisanie jakiegoś kodu z opisem które atrybuty są które, i sposób zmiany ich wartości...

Pozdrawiam
Zapisane
« Odpowiedz #1 : 20:47 23/08/11 »
khonsu Offline
Professional Python User

Zobacz profil
***

Reputacja: 93
Wiadomości: 425


Klasy i instancje klas mają swoje własne przestrzenie nazw. Wszędzie tam gdzie podczas pisania klasy, poprzedzasz nazwy zmiennych i metod przedrostkiem self odwołujesz się do przestrzeni nazw instancji tej klasy, w przeciwnym przypadku do przestrzeni nazw klasy.

Instancja klasy to obiekt utworzony poprzez wywołanie tej klasy, w taki sposób jak byś wywoływał klasę jako funkcję czyli np.:
Kod
instancja_1 = przykladowa_klasa()
instancja_2 = przykladowa_klasa()
instancja_3 = przykladowa_klasa()
...
instancja_n = przykladowa_klasa()
takie wywołanie klasy zwraca jej instancję, (to dlatego w metodzie __init__ klasy nie może być używane słowo kluczowe "return", bo efekt wywołania "instancja_n = przykladowa_klasa()" jest równoznaczny z wywołaniem metody __init__ tej klasy, co musi skończyć się zwruceniem nowego obiektu będącego instancją tej klasy.)

Podsumowując, każdy z obiektów będący instancją klasy "przykładowa_klasa" ma własną przestrzeń nazw która w klasie oznaczana jest przez "prefix" self.

Wyobraźmy sobie przykładową sytuację, mamy daną klasę taką że:
Kod
class przykladowa_klasa():
   atrybut_klasy = 1
   def __init__(self, atrybut_instancji):
       # self jest tu odwolanłem do przyszłego jeszcze nie istniejącego obiektu będącego
       # instancją tej klasy, wartość self zostanie ustalona w momencie zainicjowania
       # takowej instancji, i zostanie na nią ustawiona, jeśli instancja nazywałaby się
       # przykładowo "instancja_n" to tak jakbyśmy pisali tu "instancja_n.atrybut_instancji"
       # zamiast "self.atrybut_instancji".
       self.atrybut_instancji = atrybut_instancji
Każda instancja (obiekt) tej klasy ma swoją własną zmienną "atrybut_instancji", bo każdy ma swoją własną przestrzeń nazw (w definicji klasy oznaczanej jako self).
I tak:
Kod
>>> instancja_1 = przykladowa_klasa(1)
>>> instancja_2 = przykladowa_klasa(2)
>>> instancja_n = przykladowa_klasa('n')
>>> instancja_1.atrybut_instancji
1
>>> instancja_2.atrybut_instancji
2
>>> instancja_n.atrybut_instancji
'n'
 
Ale zmienna "atrybut_klasy" jest już wspólna dla wszystkich jej instancji.
Tak więc:
Kod
>>> instancja_n.atrybut_klasy
1
>>> instancja_2.atrybut_klasy
1
>>> instancja_1.atrybut_klasy
1
ale jeśli zmienimy wartość tej zmiennej (atrybutu klasy) to
Kod
>>> przykladowa_klasa.atrybut_klasy = 'nowa wartosc'
>>> instancja_2.atrybut_klasy
'nowa wartosc'
>>> instancja_1.atrybut_klasy
'nowa wartosc'
>>> instancja_n.atrybut_klasy
'nowa wartosc'
co pokazuje że zmienna "atrybut_klasy" faktycznie jest "wspólna" dla wszystkich instancji klasy "przykladowa_klasa", ponieważ należy ona do przestrzeni nazw klasy a nie przestrzeni nazw poszczególnych instancji tej klasy, w definicji klasy nie została ona poprzedzona prefiksem "self."

Ponieważ klasa sama jest obiektem, możemy ją dowolnie modyfikować np. dodawać, usuwać jej atrybuty i metody.
Kod
>>> przykladowa_klasa.nowy_atrybut = 'nowy'
i tym samym wszystkie instancje tej klasy mają dostęp do tego atrybutu
Kod
>>> instancja_2.nowy_atrybut
'nowy'
oraz, po usunięciu tego atrybutu żadna go nie będzie miała:
Kod
>>> del przykladowa_klasa.atrybut_klasy
>>> instancja_2.atrybut_klasy
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'przykladowa_klasa' object has no attribute 'atrybut_klasy'

Tak więc różnica pomiędzy atrybutami klasy i atrybutami instancji jest taka że te pierwsze są wspólne dla wszystkich instancji danej klasy, podczas gdy te drugie ograniczają się swym zasięgiem do danej instancji.


Każda funkcja zdefiniowana w "ciele" klasy jest nazywana jej metodą, każda metoda klasy (poza specjalnymi wyjątkami np. metody z dekoratorem @clasmethod) jako pierwszy swój parametr przyjmuje "odwołanie" (referencje) do przyszłej instancji tej klasy, oznaczaliśmy ten parametr jako "self", ale takie nazewnictwo to tylko konwencja, to może być dowolna nazwa, np. w Javie i JavaScripcie używa się this, ważne by był to pierwszy parametr funkcji, tak więc każda metoda jakiejś klasy musi przyjmować przynajmniej jeden parametr, np.:
Kod
class k():
   def m(self):
       # self jest pierwszym parametrem funkcji(metody) "m" jest więc automatycznie
       # odwolaniem do przestrzeni nazw instancji tej klasy
       self.attr = 'cos tam'
 
   def n(dowolna_nazwa_parametru):
       # "dowolna_nazwa_parametru" również jest odwołaniem do instancji tej klasy
       # ponieważ jest nazwą pierwszego parametru tej metody/funkcji
       dowolna_nazwa_parametru.attr = 'cos innego'
oba parametry - mimo rożnych nazw - odwołują się do instancji klasy (do jej przestrzeni nazw)
Kod
# metoda m tworzy atrybut instancji "inst" o nazwie "attr" i nadaje mu wartość "coś tam"
>>> inst.m()
>>> inst.attr
'cos tam'
>>> inst.n() # metoda "n" zmienia tę wartość na "coś innego"
>>> inst.attr
'cos innego'

Podsumowując, atrybuty instancji tworzy się, poprzez przypisanie tego atrybutu, pierwszemu parametrowi metody, w której tworzy się ten atrybut, zwykle (na mocy nie pisanej konwencji) jest to "self".

Każda funkcja/metoda ma własną przestrzeń nazw. O zmiennych zadeklarowanych w funkcji mówi się że są "lokalne" dla tej funkcji, tzn. że jeśli zdefiniujemy zmienną powiedzmy x w funkcji f to ta zmienna istnieje tylko w funkcji f np.:
Kod
>>> def f():
...     x = 'jakaś wartość'
# zmienna x nie istnieje poza funkcją "f"
>>> x
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

Wynikają stąd ograniczenia w definiowaniu atrybutów klas i instancji tychże klas.
Atrybut instancji klasy może zostać nadany/usunięty/zmodyfikowany tylko w obrębie metody tej klasy (tylko wtedy mamy dostęp do parametru "self").
Atrybuty klasy definiuje się zwykle w "ciele" klasy nie w metodach, w metodach danej klasy odwołuje się do nich poprzez prefiks będący nazwą klasy i operator wyszukiwania ".", np.:
Kod
class k():
   # atrybut klasy
   attr = 'foo'
 
   def m(self):
       # lokalna zmienna attr dla metody m, nie ma powiązania z atrybutem klasy "k" o tej samej nazwie
       attr = 'bar'
   def n(self):
       # modyfikacja atrybutu "attr" klasy "k"
       k.attr = 'oopan'
i dalej:
Kod
>>> x.attr
'foo'
>>> k.attr
'foo'
>>> x.m()
>>> x.attr
'foo'
>>> k.attr
'foo'
atrybut klasy się ni e zmienił, ale:
Kod
>>> x.n()
>>> x.attr
'oopan'
>>> k.attr
'oopan'
tu już tak.

Nie ma formalnego ograniczenia które zabraniało by tworzyć atrybuty klas w metodach (choć ja się nie spotkałem), robi się to tak jak z każdym innym obiektem poprzez przypisanie:
Kod
nazwa_klasy.atrybut = wartość.

Wszystko na temat atrybutów klas i metod, rozgadałem (pisałem) się, gdyby coś jeszcze było niejasne to pisz.

Pozdrawiam.
Zapisane

There are 10 kinds of people:
Those who understand binary and those who don't
« Odpowiedz #2 : 20:56 23/08/11 »
cji Offline
Advanced Python User

Zobacz profil WWW
**

Reputacja: 22
Wiadomości: 148


@khonsu

Plusik masz u mnie, dobre wyjasnienie. Jak sie pokusisz jeszcze o opis metaklas, to bedzie kompletne Uśmiech
Zapisane
« Odpowiedz #3 : 21:05 23/08/11 »
jaras Offline
Advanced Python User

Zobacz profil
**

Reputacja: 30
Wiadomości: 191


Tak więc różnica pomiędzy atrybutami klasy i atrybutami instancji jest taka że te pierwsze są wspólne dla wszystkich instancji danej klasy, podczas gdy te drugie ograniczają się swym zasięgiem do danej instancji.
nie wiem czy użyłbym tutaj stwierdzenia wspólne dla wszystkich instancji danej klasy, bo można to źle zinterpretować:
Kod
>>> class test():
...     atrybut_klasy = 1
>>> t1 = test()
>>> t2 = test()
>>> t1.atrybut_klasy = 2
>>> t2.atrybut_klasy
1

ja raczej myślę o tym jak o wartości domyśłnej
Zapisane
« Odpowiedz #4 : 21:33 23/08/11 »
khonsu Offline
Professional Python User

Zobacz profil
***

Reputacja: 93
Wiadomości: 425


nie wiem czy użyłbym tutaj stwierdzenia wspólne dla wszystkich instancji danej klasy, bo można to źle zinterpretować:

Masz rację, to może być mylące, ale ma swoje uzasadnienie (przyznaje nie je ono bynajmniej oczywiste):

Kod
>>> class test():
...     atrybut_klasy = 1
>>> t1 = test()
>>> t2 = test()
>>> t1.atrybut_klasy = 2
 
Ponieważ instancja t1 nie posiada - w swojej lokalnej przestrzeni nazw - atrybutu "atrybut_klasy" zostaje on utworzony i ustawiony na 2, tym samym przysłonięty zostaje atrybut klasy o takiej samej nazwie, i nie można go już czytać za pomocą operatora "kropkowego", ale nadal mamy:
Kod
>>>test.atrybut_klasy
1
Tutaj:
Kod
>>> t2.atrybut_klasy
1
mamy analogiczną sytuację operator "kropkow" szuka atrybutu "atrybut_klasy" w lokalnej przestrzeni nazw instancji "t2" klasy "test", po czym nie znajdując jej szuka w globalnej przestrzeni nazw, tą globalną przestrzenią jest tutaj przestrzeń nazw klasy.

Analogiczna sytuacja występuje w przypadku zwykłych funkcji:
Kod
>>>x = 'foo'
>>>def f():
...    return x
>>>f()
'foo'
funkcja f zwraca zmienną x z przestrzeni dla niej globalnej bo w lokalnej dla niej (wewnątrz f) takiej zmiennej niema.
Zapisane

There are 10 kinds of people:
Those who understand binary and those who don't
« Odpowiedz #5 : 01:29 24/08/11 »
LQC Offline
Python God

Zobacz profil
*****

Reputacja: 226
Płeć: Mężczyzna
Wiadomości: 1000


nie wiem czy użyłbym tutaj stwierdzenia wspólne dla wszystkich instancji danej klasy, bo można to źle zinterpretować:

Ależ one są "wspólne", bo wszystkie instancje mają tą samą klasę na której składowana jest ta wartość. Myli cię jedynie sposób działania przypisania (__setattr__):

Kod
class A(object):
   x = []
 
a = A()
b = A()
a.x.append(42)
assert b.x == a.x == [42]
b.x.append(13)
assert b.x == [42, 13]
 

I to jest powód dlaczego nigdy nie należy używać obiektów o zmiennym stanie jako atrybutów klasy.
Zapisane

Dołącz do projektu Wolnelektury.pl na github (open-source, pro publico bono)
« Odpowiedz #6 : 10:02 24/08/11 »
jaras Offline
Advanced Python User

Zobacz profil
**

Reputacja: 30
Wiadomości: 191


Ponieważ instancja t1 nie posiada - w swojej lokalnej przestrzeni nazw - atrybutu "atrybut_klasy" zostaje on utworzony i ustawiony na 2, tym samym przysłonięty zostaje atrybut klasy o takiej samej nazwie, i nie można go już czytać za pomocą operatora "kropkowego"
i właśnie dlatego nie napisałem, że tak nie jest, tylko że bym tego tak nie nazwał... Z politowaniem

edit: może inaczej - przez całą swoją programistyczną karierę nie pamiętam abym musiał zmieniać atrybut klasy, stąd też moje przeświadczenie, poparte statystyką z co prawda bardzo małej próbki, że prawdopodobnie nieczęsto się to robi, jeśli w ogóle.
Zapisane
« Odpowiedz #7 : 13:51 24/08/11 »
sebatbg Offline
Hello World!

Zobacz profil
*

Reputacja: -1
Wiadomości: 24


Witam

@khonsu - dziękuję za bardzo wyczerpującą odpowiedź...
Powoli te kwestie stają się dla mnie jasne...
Cały temat sobie wydrukowałem, więc będę go sobie jeszcze wiele razy czytał, żeby wszystko było dla mnie wiadome...

Mam jednak jeszcze 1 pytanie...:

Z tego co zauważyłem atrybuty instancji mogą występować tylko w metodach, w przeciwieństwie do atrybutów klasy znajdujących się pomiędzy class a pierwszym def...

Co w metodzie oznacza przypisanie self.atrybut_instancji = atrybut_instancji?

Chodzi może o to ,żeby tego argumentu dzięki selfowi używać w pozostałych metodach
Zapisane
« Odpowiedz #8 : 14:09 24/08/11 »
konradkur
Gość
Kod
Co w metodzie oznacza przypisanie self.atrybut_instancji = atrybut_instancji?
self to instancja Co?
Zapisane
« Odpowiedz #9 : 14:11 24/08/11 »
pigmej Offline
PPCG
Professional Python User

Zobacz profil
*****

Reputacja: 50
Płeć: Mężczyzna
Wiadomości: 343


Chodzi może o to ,żeby tego argumentu dzięki selfowi używać w pozostałych metodach

W skrócie tak.
'self' to to samo co 'this' w Java na przyklad. Tylko ze w Pythonie 'self' trzeba podawac jawnie (zawsze pierwszy agument nie statycznej metody klasy). Z ciekawostek mozna wspomniec to ze mozesz zamiast 'self' napisac 'ja_sama' i tez bedzie dzialac. 'self' jest umowne i tego sie nalezy trzymac Mrugnięcie
Zapisane
« Odpowiedz #10 : 17:16 24/08/11 »
khonsu Offline
Professional Python User

Zobacz profil
***

Reputacja: 93
Wiadomości: 425


Chodzi o to, że przyszła instancja tej klasy będzie miała atrybut o nazwie "atrybut_instancji" o wartości danej po prawej stronie znaku równości - to jest zwykłe przypisanie.

W pythonie w każdej chwili możesz do obiektu dodać nowy atrybut, robi się to za pomocą "przypisania", składnia jest taka:

obiekt . atrybut = wartość

to tak jakbyś deklarował zwykłą zmienną:

zmienna = wartość

różnica jest taka że, nie robisz tego globalnie dla całego programu tylko dla konkretnego obiektu, tym samym twoja zmienna (dalej w tym kontekście nazywana atrybutem) będzie widoczna i dostępna tylko za pośrednictwem tego obiektu, np.:

tworzymy przykładową klasę:
Kod
class K():
pass
tworzymy obiekt będący instancją tej klasy
Kod
x = K()
teraz dodajemy do obiektu x (instancji klasy K) jakiś atrybut, za pomocą
operacji przypisania, np.:
Kod
x.value = 42
"value" jest tu nazwą zmiennej (atrybutu) obiektu x, i jest dostępna tylko za pośrednictwem tego obiektu, wartością tego atrybutu jest liczba "42"
Kod
>>> x.value
42
albo:
Kod
>>> x.description = 'Odpowiedź na "Ostateczne Pytanie dotyczące Życia, Wszechświata i Całej Reszty".'
gdzie:
x - nazwa obiektu
. - operator kropkowy (za jego pomocą odwołujesz się do przestrzeni nazw obiektu)
description - nazwa atrybutu
'Odpowiedź na "Ostateczne Pytanie dotyczące Życia, Wszechświata i Całej Reszty".' - jego wartość

w efekcie mamy:
Kod
>>> x.description
'Odpowiedź na "Ostateczne Pytanie dotyczące Życia, Wszechświata i Całej Reszty".'
Wracając do twojego pytania, każda (nie statyczna) metoda w klasie jako pierwszy swój parametr przyjmuje obiekt (dalej nazywany self), obiekt ten to przyszła instancja tej klasy. Wyobraź sobie zwykłą funkcję taką że:
Kod
>>> def dodaj_jeden(x):
... return x + 1
W momencie definiowania tej funkcji, "x" nie jest jeszcze znane, ale to nie przeszkadza ci w zdefiniowaniu procedury, która coś z tym x-em zrobi, wartość "x" zostanie ustalona w momencie wywołania tej funkcji, np.:
Kod
>>> dodaj_jeden(42)
43
wartość "x" w momencie wywołania funkcji została ustalona na 42, czyli to jest tak jak gdybyś napisał
Kod
>>> def dodaj_jeden(42):
... return 42 + 1
Podobnie jest z metodami klas, metoda jako pierwszy argument przyjmuje self, a ty możesz na self (tak jak na x) przeprowadzać jakieś działania, wartość self zostanie ustalona w momencie stworzenia instancji klasy, np.:
Kod
>>> class A():
... def m(self, jakies_imie):
... self.imie = jakies_imie
Teraz twożymy instancję klasy A:
Kod
>>> a = A()
I w tym momencie "self" w definicji klasy zostało ustalone na a, wszystkie operacje które przeprowadzasz na "self", przeprowadzasz na a, np. pisząc:

Kod
>>>a.m('Koziołek Matołek')
to tak jak gdybyś napisał:
Kod
>>> class A():
... def m(a, "Koziołek Matołek")
... a.imie = "Koziołek Matołek"
tym samym w metodzie "m" nadałeś instancji klasy "A" atrybut o nazwie "imie" i wartości "jakies_imie".
W naszym konkretnym przypadku, nadałeś instancji "a" atrybut "imie" o wartości "Koziołek Matołek":
Kod
>>>a.imie
'Koziołek Matołek'
Jest tak dla każdej instancji klasy A:
Kod
>>> a_1 = A()
>>> a_2 = A()
>>> a_1.m('Bolek')
>>> a_2.m('Lolek')
Obie instancje, tzn.: a_1 i a_2, mają atrybut "imie", ale jego wartość jest różna:
Kod
>>> a_1.imie
'Bolek'
>>> a_2.imie
'Lolek'
Jest tak ponieważ, dla instancji a_1 parametr self został ustawiony na a_1, natomiast dla a_2 na a_2. Są to dwa różne obiekty i mają oddzielne przestrzenie nazw, ale są instancjami tej samej klasy, przestrzeń nazw klasy jest więc dla nich wspólna, i tak:
Kod
>>> a_1.nazwisko = 'Kowalski'
spowoduje dodanie do obiektu a_1 atrybutu nazwisko o wartości 'Kowalski'
Kod
>>> a_1.nazwisko
'Kowalski'
obiekt a_2 tego atrybutu nie posiada:
Kod
>>> a_2.nazwisko
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'nazwisko'
ale dodanie atrybutu do klasy A (pamiętajmy że klasa jest również obiektem, możemy więc dodawać do niej atrybuty), spowoduje że wszystkie instancje tej klasy, będą miały do niego dostęp, i tak:
Kod
>>> A.atrybut_klasy = 'oopan'
>>> a_1.atrybut_klasy
'oopan'
>>> a_2.atrybut_klasy
'oopan'
Jest tak ponieważ obie instancje mają wspólną klasę.

Podsumowując 'self' zawsze oznacza przyszłą instancję klasy, wszystko co robisz na 'self' robisz na tej instancji, możesz więc dodawać do instancji nowe atrybuty (dlatego się tak nazywają, tzn. "atrybuty instancji" Mrugnięcie), modyfikować ich wartość czy usuwać.
Wszystko to robisz odwołując się do 'self' i wszystko co robisz na 'self' ogranicza się do JEDNEJ konkretnej instancji. I dalej 'self' występuje we wszystkich metodach klasy, tym samym we wszystkich tych metodach masz dostęp do TEJ SAMEJ instancji tej klasy, np.:
Kod
>>> class B():
... def dodaj(self):
... self.attr = 'oopan'
... def usun(self):
... del self.attr
>>> b_1 = B()
>>> b_2 = B()
>>> b_1.dodaj()
>>> b_2.dodaj()
teraz obie instancje mają atrybut o nazwie "attr", utworzony w metodzie "dodaj":
Kod
>>> b_1.attr
'oopan'
>>> b_2.attr
'oopan'
ale jeśli wywołamy metodę "usun" na obiekcie b_1, to:
Kod
>>> b_1.usun()
>>> b_1.attr
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'B' object has no attribute 'attr'
skasowaliśmy atrybut "attr" instancji b_1, podczas gdy instancja b_2:
Kod
>>> b_1.attr
'oopan'
nadal go ma, widać więc że dla wszystkich metod klasy, odwołanie do self, jest odwołaniem do tej samej, konkretnej, instancji tej klasy.

Czyli po raz kolejny, poprzez "self" odwołujesz się do przestrzeni nazw instancji, jednej konkretnej instancji, czyli są to atrybuty i metody instancji, tym różnią się właśnie atrybuty instancji i atrybuty klasy, te drugie są wspólne dla wszystkich instancji, te pierwsze nie.

Z tego co zauważyłem atrybuty instancji mogą występować tylko w metodach, w przeciwieństwie do atrybutów klasy znajdujących się pomiędzy class a pierwszym def...

Tylko w metodach bo tylko w metodach masz dostęp do obiektu instancji, czyli do self. Atrybuty klasy mogą występować gdziekolwiek w klasie, przed metodami, po metodach i (uwaga) w metodach, różnica jest taka że jeśli używasz albo deklarujesz atrybut klasy w metodzie, to musisz go poprzedzić nazwą klasy: nazwa_klasy.atrybut
Kod
>>> class K():
... attr = 'oopan'
... def usun_1(self):
... del attr
... def usun_2(self):
... del K.attr
pierwsza metoda "usun_1" nie zadziała:
Kod
>>> inst = K()
>>> inst.usun_1()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<stdin>", line 4, in usun_1
UnboundLocalError: local variable 'attr' referenced before assignment
>>> K.attr
'oopan'
ponieważ nie wiadomo, gdzie szukać zmiennej "attr", natomiast druga metoda:
Kod
>>> inst.usun_2()
>>> K.attr
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: type object 'K' has no attribute 'attr'
już tak, ponieważ poprzedziliśmy ją nazwą klasy, czyli szukamy tej nazwy (attr) w klasie K (w jej przestrzeni nazw).
W taki sposób można odwoływać się do metod klasy, w jej metodach, po prostu zwyczajnie, przeprowadzając działania na obiekcie, którym jest ta klasa, wewnątrz niej samej.

Uff... Koniec.

Pozdrawiam
Zapisane

There are 10 kinds of people:
Those who understand binary and those who don't
« Odpowiedz #11 : 11:38 25/08/11 »
sebatbg Offline
Hello World!

Zobacz profil
*

Reputacja: -1
Wiadomości: 24


Witam

@khonsu
Kolejny raz kieruję w twoją stronę ukłony za wyczerpujące objaśnienie tematu...
Nie mam więcej pytań...rozwiałeś wszelkie moje wątpliwości...
Oczywiście to również zostało wydrukowane i dołączone do poprzedniego...

Proponuję aby ten wątek dokleić do wątku przyklejonego autorstwa zuo, lub też przykleić jako osobny temat...

Opisywane zagadnienie jest wyjaśnione tak przejrzyście, że według mnie zasługuje na przyklejenie...

Dziękuję za pomoc

Pozdrawiam
Zapisane
Strony: [1]   Do góry
Drukuj
Skocz do:  

© 2007 - 2019 Polish Python Coders Group
Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines | Theme by PixelSlot