W języku Python typy danych przypisywane są automatycznie, nigdy nie deklaruje się ich w kodzie. Zmienna utworzona zostaje w momencie kiedy pop raz pierwszy zostanie przypisana (instrukcja przypisania) jej jakakolwiek wartość. Wszystkie zmienne zanim zostaną użyte muszą posiadać przypisane wartości. W momencie przypisania wartości zmienna staje się referencją do obiektu na który wskazuje. Mówiąc inaczej jest wskaźnikiem do miejsca w pamięci, w którym przechowywany jest obiekt.
# Instrukcja przypisania
zmienna = 15
W powyższym przykładzie zostają wykonane następujące kroki:
1. zostaje utworzony obiekt liczbowy o wartości 15
2. zostaje utworzona zmienna o nazwie zmienna
(jeśli nie istniała wcześniej)
3. obiekt liczbowy zostaje przypisany do zmiennej
Zmienne nie posiadają typów, te dotyczą wyłącznie wskazywanych przez nie obiektów.
# Zmiana wartości zmiennej a
a = 234; a = 'Python'; a = 3.14
Ponieważ zmienne nie posiadają typów, więc powyższy przykład wskazuje na zmianę przypisanego obiektu do zmiennej a
. Python rozpoznaje typ przypisanego obiektu poprzez tzw. desygnator typu. Jeśli ta sama zmienna zostanie przypisana do nowego obiektu to automatycznie zostanie zwolnione miejsce w pamięci zajmowane przez obiekt poprzedni. Za czyszczenie pamięci odpowiada mechanizm zwany garbage collection (taki automatyczny destruktor).
# Ostatecznie zmienna a ma wartość 3.14
a = 234; a = 'Python'; a = 3.14
# pamięć po obiektach 234 i 'Python' zostaje automatycznie odzyskana a referencje rozwiązane
Każdy obiekt poza desygnatorem posiada także licznik referencji, który 'śledzi' każdą referencję do danego obiektu. Obiekt może posiadać referencję do wielu zmiennych, ale jeśli wartość licznika spadnie do zera (obiekt nie posiada już żadnych referencji) to czyszczenie pamięci zostaje automatycznie uruchomione.
Referencje współdzielone
Polega to na tym, że kilka zmiennych posiada referencję do tego samego obiektu.
z_1 = 21343; z_2 = z_1
# z_2 ma wartość 21343
Do z_2 została przypisana wartość z_1, nie sama zmienna. Jest to klasyczna referencja współdzielona (ang. shared references) czyli kilka zmiennych odnosi się to jednego obiektu.
Zmiana wartości jednej ze zmiennych współdzielonych:
z_1 = 5; z_2 = z_1; z_1 = 'Python'
# wynik z_1 = 'Python', z_2 = 5
Ponieważ z_2 jest nowym obiektem to późniejsza zmiana wartości zmiennej z_1 nie ma wpływy na wartość z_2. Do zmiennej z_2 została przypisana wartość 5 (z wykorzystaniem zmiennej z_1) i nie uległa ona zmianie.
Referencje współdzielone, wpływ na inne obiekty
l_1 = ['jeden', 2, 'trzy', 4]
l_2 = l_1
l_1[0] = 1; l_1[2] = 3
# wynik: listy l_1 i l_2 mają wartość [1, 2, 3, 4]
Ponieważ zmieniony został jedynie fragment współdzielonej listy zmiana ta odnosi się do wszystkich referencji, wartość zmiennej l_2 została nadpisana. Aby zapobiec tego typu nadpisaniom obiektów można zastosować kopie zamiast referencji. W takim przypadku referencje odnoszą się do różnych obiektów.
# kopia listy
l_1 = ['jeden', 2, 'trzy', 4]
l_2 = l_1[:]
l_1[0] = 1; l_1[2] = 3
# wynik: lista l_1 ma wartość [1, 2, 3, 4], l_2 pozostaje bez zmian
# kopia słownika
s = {'a': 10, 'd': 211, 'b': 24, 'c': 50}
s2 = s.copy()
Porównania referencji i wartości
Poprzez wykorzystanie operatora is
można sprawdzić czy obiekty są tego samego typu, porównanie wartości odbywa się za pomocą operatora ==
.
# referencja współdzielona
l_1 = ['jeden', 2, 'trzy', 4]
l_2 = l_1
l_1 == l_2 # wynik: True, wartość ta sama
l_1 is l_2 # wynik True, obiekt ten sam
# porównanie list
l_1 = ['jeden', 2, 'trzy', 4]
l_2 = ['jeden', 2, 'trzy', 4]
l_1 == l_2 # wynik: True, wartość ta sama
l_1 is l_2 # wynik False, obiekt nie jest ten sam
# porównanie liczb
a = 15; b = 15
a == b # wynik: True, wartość ta sama
a is b # wynik True, obiekt ten sam
# wynik powinien być False, ale małe liczby zapisane są w pamięci podręcznej
# dla ich szybkiego ponownego użycia
Sprawdzenie ilości referencji do danego obiektu.
Dzięki funkcji getrefcount() z modułu sys zwraca ilość referencji dla danego obiektu.
# sprawdzenie ilości referencji dla stringa 'python'
import sys
sys.getrefcount('python')
# sprawdzenie ilości referencji dla obiektu liczby 3
sys.getrefcount(3.14)
Zasady prawidłowego nazewnictwa zmiennych
1. Nazwy zmiennych mogą zawiera jedynie litery, cyfry oraz znaki podkreślenia _
. Litery mogą być małe lub wielkie (ASCII lub Unicode, bez znaków narodowych). Zazwyczaj wielkimi literami zapisuje się nazwy zmiennych o wartościach stałych. Nazwa zmiennej nie może zaczynać się od cyfry.
# zmienne nazwane poprawnie
a = 12; content_1 = {}; STATUS = ('active', True)
# zmienne nazwane błędnie
123 = "content"; 1_content = {}; źdźbło = ()
2. Zabronione jest stosowanie spacji, jako separator może służyć znak podkreślenia _
lub zapis z wykorzystaniem kombinacji liter wielkich i małych (wielkość liter ma znacznie). Uwaga na litery takie jak małe 'l' i duże 'O'.
# zmienne nazwane poprawnie
blog_post = {}; blogPost = {}
# zmienne nazwane błędnie
blog post = {}; lO = 'czy to małe l czy duże i, zero a może duże o?'
3. Nazwa zmiennej powinna być krótka, więzła ale jednocześnie oddająca jej faktyczną zawartość.
# zmienne nazwane czytelnie
user_name = ''; blogContent = {}; active = True
# zmienne nieczytelne, niezrozumiałe
u_n = ''; bC = {}; a = True
# ostro przesadzona nazwa zmiennej :)
first_name_and_last_name_of_our_website_user = ''; a_na_imie_jej_bylo = 'Lily'
4. Absolutny zakaz korzystania ze słów kluczowych Pythona podczas tworzenia zmiennych! Uwaga na stosowanie podkreśleń na krańcach nazwy zmiennych, mają one swoje specjalne znaczenie.
# niektóre słowa kluczowe Pythona
and del for is raise
assert elif from lambda return
break else global not try
class except if or while
continue exec import pass yield
def finally in print
# przykładowe specjalne nazwy metod:
__init__ __del__ __str__ __get__