2.2. Variabili e tipi di base

Una variabile è un nome che associ a un valore con l’operatore =. Dopo l’assegnazione, il nome può essere usato ovunque possa esserlo il valore:

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

Il lato destro di = viene valutato per primo, poi il risultato viene associato al nome a sinistra. Leggere un nome che non è mai stato assegnato solleva un NameError.

Una variabile è solo un’etichetta. Punta a un valore – il valore risiede altrove, e lo stesso valore può avere un numero qualsiasi di etichette.

Tre etichette che puntano a tre valori inscatolati; riassegnare un'etichetta sposta la freccia, non il valore.

Le variabili sono etichette che puntano a valori. Riassegnare una variabile sposta l’etichetta; non cambia il valore a cui l’etichetta puntava in precedenza.

2.2.1. Regole di denominazione

  • I nomi iniziano con una lettera o un trattino basso e possono contenere lettere, cifre e trattini bassi. frame_count e _internal vanno bene; 1st_frame è un errore di sintassi.

  • I nomi distinguono tra maiuscole e minuscole: Width e width sono due variabili diverse.

  • Evita di riutilizzare nomi integrati come list, str, id() o print() – oscurarli non solleva un errore, ma l’originale integrato diventa irraggiungibile per il resto dello script.

  • Convenzione: snake_case per variabili e funzioni, ALL_CAPS per le costanti che non intendi modificare, CamelCase per i nomi delle classi.

2.2.2. Tipi di base

Ogni valore in Python ha un tipo che determina quali operazioni supporta. I quattro tipi che scriverai più spesso sono:

  • int – numeri interi, positivi o negativi. Gli interi di MicroPython crescono fino a quanto la memoria consente. I letterali si scrivono come semplici cifre: 0, 42, -7. Sono validi e utili anche i letterali esadecimali (0x1A), ottali (0o17) e binari (0b1010) per registri e maschere di bit.

  • float – numeri con una virgola decimale o un esponente: 3.14, 1.0, -0.5, 2e6 (= 2.000.000,0). Tutti i float sulla camera sono IEEE 754 a 32 bit – precisi fino a circa sette cifre significative.

  • bool – uno dei due letterali True o False (nota le maiuscole).

  • str – testo, scritto come caratteri tra virgolette singole o doppie: "hello", 'OpenMV'. Entrambi gli stili di virgolette sono equivalenti; scegli quello che ti permette di evitare l’escape dei caratteri di virgoletta che compaiono all’interno della stringa.

C’è anche un quinto valore che vale la pena conoscere subito:

  • None – l’unico valore di tipo NoneType. Usato per indicare «nessun valore» o «non ancora impostato». Le funzioni che non restituiscono esplicitamente nulla restituiscono implicitamente None.

2.2.3. Verificare e convertire i tipi

La funzione integrata type() restituisce il tipo di qualsiasi valore:

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

Ogni tipo funge anche da funzione di conversione. Passale un valore di tipo diverso e otterrai indietro il valore equivalente del nuovo tipo – quando la conversione è ben definita:

>>> 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)

Le conversioni che non sono ben definite sollevano un 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. Riassegnazione e tipizzazione dinamica

Un nome può essere riassegnato a un valore di qualsiasi tipo in qualsiasi momento. Quanto segue è lecito:

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

Python non associa una variabile a un tipo. Il codice che dipende dal fatto che x sia un intero si aspetta semplicemente un intero nel punto in cui lo usa; se ottiene qualcos’altro, ricevi un TypeError in fase di esecuzione.

Nota

Riassegnare x non cambia il valore a cui puntava la vecchia associazione. Se due nomi condividono lo stesso valore, riassegnarne uno non influisce sull’altro:

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

Mutare un valore condiviso è diverso: un metodo come list.append cambia il valore a cui punta l’associazione, quindi ogni altro nome che punta a quello stesso valore vede il cambiamento.