2.2. Zmienne i podstawowe typy

Zmienna to nazwa, którą wiążesz z wartością za pomocą operatora =. Po przypisaniu nazwy można użyć wszędzie tam, gdzie można użyć wartości:

width = 320
height = 240
pixels = width * height
print(pixels)               # prints 76800

Najpierw ewaluowana jest prawa strona =, a następnie wynik jest wiązany z nazwą po lewej stronie. Odczytanie nazwy, która nigdy nie została przypisana, zgłasza NameError.

Zmienna to po prostu etykieta. Wskazuje na wartość – wartość znajduje się gdzie indziej, a ta sama wartość może mieć dowolną liczbę etykiet.

Trzy etykiety wskazujące na trzy zapakowane wartości; ponowne przypisanie etykiety przesuwa strzałkę, a nie wartość.

Zmienne to etykiety wskazujące na wartości. Ponowne przypisanie zmiennej przesuwa etykietę; nie zmienia wartości, na którą etykieta wcześniej wskazywała.

2.2.1. Reguły nazewnictwa

  • Nazwy zaczynają się od litery lub podkreślenia i mogą zawierać litery, cyfry oraz podkreślenia. frame_count i _internal są poprawne; 1st_frame to błąd składni.

  • Nazwy rozróżniają wielkość liter: Width i width to dwie różne zmienne.

  • Unikaj ponownego używania nazw wbudowanych, takich jak list, str, id() czy print() – przesłonięcie ich nie zgłasza błędu, ale oryginalny element wbudowany staje się niedostępny przez resztę skryptu.

  • Konwencja: snake_case dla zmiennych i funkcji, ALL_CAPS dla stałych, których nie zamierzasz zmieniać, oraz CamelCase dla nazw klas.

2.2.2. Podstawowe typy

Każda wartość w Pythonie ma typ, który określa, jakie operacje obsługuje. Cztery typy, których będziesz używać najczęściej, to:

  • int – liczby całkowite, dodatnie lub ujemne. Liczby całkowite w MicroPython rosną tak duże, jak pozwala na to pamięć. Literały zapisuje się jako zwykłe cyfry: 0, 42, -7. Literały szesnastkowe (0x1A), ósemkowe (0o17) i binarne (0b1010) są również poprawne i przydatne dla rejestrów oraz masek bitowych.

  • float – liczby z kropką dziesiętną lub z wykładnikiem: 3.14, 1.0, -0.5, 2e6 (= 2 000 000,0). Wszystkie liczby zmiennoprzecinkowe na kamerze są 32-bitowe w standardzie IEEE 754 – dokładne do około siedmiu cyfr znaczących.

  • bool – jeden z dwóch literałów True lub False (zwróć uwagę na wielkość liter).

  • str – tekst zapisany jako znaki między pojedynczymi lub podwójnymi cudzysłowami: "hello", 'OpenMV'. Oba style cudzysłowów są równoważne; wybierz ten, który pozwoli ci uniknąć escapowania znaków cudzysłowu pojawiających się wewnątrz łańcucha.

Istnieje również piąta wartość, którą warto poznać od razu:

  • None – jedyna wartość typu NoneType. Używana w znaczeniu „brak wartości” lub „jeszcze nie ustawiono”. Funkcje, które nie zwracają niczego jawnie, niejawnie zwracają None.

2.2.3. Sprawdzanie i konwertowanie typów

Funkcja wbudowana type() zwraca typ dowolnej wartości:

>>> type(42)
<class 'int'>
>>> type(3.14)
<class 'float'>
>>> type("hello")
<class 'str'>

Każdy typ pełni również rolę funkcji konwertującej. Podaj jej wartość innego typu, a otrzymasz równoważną wartość nowego typu – o ile konwersja jest dobrze zdefiniowana:

>>> int("42")
42
>>> int(3.9)
3                           # truncates toward zero, not rounds
>>> float("1.5")
1.5
>>> str(255)
'255'
>>> bool(0), bool(1), bool("")
(False, True, False)

Konwersje, które nie są dobrze zdefiniowane, zgłaszają ValueError:

>>> int("hello")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid syntax for integer with base 10

2.2.4. Ponowne przypisanie i typowanie dynamiczne

Nazwę można w dowolnym momencie ponownie przypisać do wartości dowolnego typu. Poniższe jest poprawne:

x = 42
x = "now I'm a string"
x = 3.14

Python nie wiąże zmiennej z typem. Kod, który zależy od tego, że x jest liczbą całkowitą, po prostu oczekuje liczby całkowitej w miejscu, w którym jej używa; jeśli otrzyma coś innego, dostaniesz w czasie wykonania TypeError.

Informacja

Ponowne przypisanie x nie zmienia wartości, na którą wskazywało stare wiązanie. Jeśli dwie nazwy współdzielą tę samą wartość, ponowne przypisanie jednej nie wpływa na drugą:

a = [1, 2, 3]
b = a                       # both point at the same list
a = "different now"
print(b)                    # still [1, 2, 3]

Mutowanie współdzielonej wartości to co innego: metoda taka jak list.append zmienia wartość, na którą wskazuje wiązanie, więc każda inna nazwa wskazująca na tę samą wartość widzi tę zmianę.