Obiekty Pythona

To jest tekst autorstwa Fredrika Lundh'a, jednego z czołowych deweloperów Pythona. Oryginał można znaleźć tutaj python-objects.

Jest to krótkie i zwięzłe podsumowanie na temat obiektów w Pythonie.

Wprowadzenie

Zresetuj swój mózg.

Obiekty

Wszystkie obiekty mają:

  • unikalny identyfikator (integer zwracany przez id(x))
  • typ (zwracany przez type(x))
  • jakąś zawartość

Nie możesz zmienić identyfikatora.

Nie możesz zmienić typu.

Niektóre typy pozwalają na zmianę ich zawartości (tj. bez zmiany identyfikatora lub typu)

Niektóre obiekty nie pozwalają na zmianę ich zawartości (więcej poniżej).

Typ jest reprezentowany przez obiekt type, który wie więcej o obiektach tego typu (ile bajtów pamięci zajmują, jakie posiadają metody itd.).

(Aktualizacja: W CPythonie 2.2 i późniejszych można zmienić typ w pewnych raczej ograniczonych okolicznościach.)

Więcej o obiektach

Obiekty mogą również mieć:

  • zero lub więcej metod (dostarczonych przez obiekt type)
  • zero lub więcej nazw

Niektóre obiekty mają metody, które pozwalają na zmianę ich zawartości (tj. modyfikację w miejscu [1]).

Niektóre obiekty mają tylko metody, które pozwalają na dostęp do zawartości bez możliwości zmiany.

Niektóre obiekty nie mają metod w ogóle.

Nawet jeśli mają jakieś metody, nie można zmienić ich typu ani identyfikatora.

Rzeczy takie jak przypisanie do atrybutów, czy dostęp do nich to jest tylko lukier syntaktyczny [2] (więcej poniżej).

Nazwy

Nazwy są nieco inne - tak naprawdę nie są one własnościami obiektu i obiekt jako taki nie wie jak się nazywa.

Obiekt może mieć dowolną ilość nazw lub nie mieć żadnej nazwy.

Nazwy żyją w przestrzeniach nazw (np. w przestrzeni nazw modułu, klasy lub lokalnej przestrzeni nazw funkcji).

Przestrzenie nazw są zbiorami par (nazwa, referencja do obiektu) zaimplementowane jako słowniki.

Gdy wywołujesz funkcję lub metodę, jej przestrzeń nazw jest inicjalizowana argumentami, z którymi ją wywołujesz (nazwy są brane z listy argumentów funkcji, natomiast obiekty podajesz Ty przy wywołaniu funkcji).

Przypisania

Instrukcje przypisania modyfikują przestrzenie nazw, a nie obiekty.

Innymi słowy:

name = 10

oznacza, iż dodajesz nazwę "name" do swojej lokalnej przestrzeni nazw i sprawiasz, że wskazuje ona na obiekt typu integer zawierający wartość 10.

Jeśli ta nazwa już istnieje, to przypisanie zastępuje oryginalną nazwę:

name = 10
name = 20

oznacza, że najpierw dodajesz nazwę "name" do lokalnej przestrzeni nazw i sprawiasz, że wskazuje ona na obiekt typu integer zawierający wartość 10. Następnie powodujesz, że wskazuje ona na obiekt zawierający wartość 20. Oryginalny obiekt "10" nie jest dotknięty tą operacją i zupełnie go to nie obchodzi.

Dla kontrastu, jeśli zrobisz tak:

name = []
name.append(1)

to dodajesz nazwę "name" do lokalnej przestrzeni nazw, "name" wskazuje na pusty obiekt listy. To modyfikuje przestrzeń nazw. Następnie wywołujesz metodę tego obiektu, mówiąc "dodaj obiekt integer do samej siebie". To modyfikuje zawartość obiektu listy, ale nie dotyka przestrzeni nazw i nie dotyka samego obiektu integer.

Rzeczy takie jak name.attr i name[index] są tylko lukrem syntaktycznym dla wywołań metod. Pierwszy odpowiada __setattr__/__getattr__, a drugi zaś __setitem__/__getitem__ (zależnie od tego po której stronie instrukcji przypisania się pojawią).

To wszystko.


[1]ang. in place - przyp. tłum.
[2]ang. syntactic sugar - przyp. tłum.