2.2. Variabelen en basistypen

Een variabele is een naam die je met de operator = aan een waarde koppelt. Na toewijzing kan de naam overal worden gebruikt waar de waarde kan worden gebruikt:

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

De rechterkant van = wordt eerst geëvalueerd, waarna het resultaat aan de naam links wordt gekoppeld. Het lezen van een naam die nooit is toegewezen, veroorzaakt een NameError.

Een variabele is slechts een label. Het wijst naar een waarde – de waarde leeft ergens anders, en dezelfde waarde kan een willekeurig aantal labels hebben.

Drie labels die naar drie ingepakte waarden wijzen; het opnieuw toewijzen van een label verplaatst de pijl, niet de waarde.

Variabelen zijn labels die naar waarden wijzen. Het opnieuw toewijzen van een variabele verplaatst het label; het verandert niet de waarde waar het label voorheen naar wees.

2.2.1. Naamgevingsregels

  • Namen beginnen met een letter of underscore en mogen letters, cijfers en underscores bevatten. frame_count en _internal zijn prima; 1st_frame is een syntaxisfout.

  • Namen zijn hoofdlettergevoelig: Width en width zijn twee verschillende variabelen.

  • Vermijd het hergebruiken van ingebouwde namen zoals list, str, id() of print() – ze overschaduwen veroorzaakt geen fout, maar de oorspronkelijke ingebouwde functie wordt onbereikbaar voor de rest van het script.

  • Conventie: snake_case voor variabelen en functies, ALL_CAPS voor constanten die je niet van plan bent te wijzigen, CamelCase voor klassenamen.

2.2.2. Basistypen

Elke waarde in Python heeft een type dat bepaalt welke bewerkingen het ondersteunt. De vier typen die je het meest zult schrijven zijn:

  • int – gehele getallen, positief of negatief. MicroPython-gehele getallen groeien zo groot als het geheugen toelaat. Literals worden geschreven als gewone cijfers: 0, 42, -7. Hexadecimale (0x1A), octale (0o17) en binaire (0b1010) literals zijn ook geldig en nuttig voor registers en bitmaskers.

  • float – getallen met een decimaalteken of een exponent: 3.14, 1.0, -0.5, 2e6 (= 2.000.000,0). Alle floats op de camera zijn IEEE 754 32-bit – nauwkeurig tot ongeveer zeven significante cijfers.

  • bool – een van de twee literals True of False (let op de hoofdletter).

  • str – tekst, geschreven als tekens tussen enkele of dubbele aanhalingstekens: "hello", 'OpenMV'. Beide aanhalingsstijlen zijn equivalent; kies welke je in staat stelt het ontsnappen van de aanhalingstekens die in de string voorkomen te vermijden.

Er is ook een vijfde waarde die het meteen waard is om te kennen:

  • None – de enige waarde van het type NoneType. Gebruikt om “geen waarde” of “nog niet ingesteld” aan te duiden. Functies die niet expliciet iets teruggeven, geven impliciet None terug.

2.2.3. Typen controleren en converteren

De ingebouwde functie type() geeft het type van elke waarde terug:

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

Elk type fungeert ook als conversiefunctie. Geef het een waarde van een ander type en je krijgt de equivalente waarde van het nieuwe type terug – wanneer de conversie goed gedefinieerd is:

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

Conversies die niet goed gedefinieerd zijn, veroorzaken een 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. Hertoewijzing en dynamische typering

Een naam kan op elk moment opnieuw worden toegewezen aan een waarde van een willekeurig type. Het volgende is legaal:

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

Python koppelt een variabele niet aan een type. Code die ervan afhangt dat x een geheel getal is, verwacht eenvoudigweg een geheel getal op het punt waar het wordt gebruikt; als het iets anders krijgt, krijg je tijdens de uitvoering een TypeError.

Notitie

Het opnieuw toewijzen van x verandert niet de waarde waar de oude koppeling naar wees. Als twee namen dezelfde waarde delen, heeft het opnieuw toewijzen van de een geen invloed op de ander:

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

Het muteren van een gedeelde waarde is anders: een methode zoals list.append verandert de waarde waar de koppeling naar wijst, dus elke andere naam die naar diezelfde waarde wijst, ziet de verandering.