Je-li Python spuštěn v neinteraktivním režimu, zkompiluje vstupní soubor do bytekódu a začne jej řádek po řádku provádět. Když narazí na definici proměnné, vytvoří někde v paměti objekt příslušného typu (číslo, slovník, seznam či jiný) a poznamená si, že toto jméno odpovídá tomuto objektu v paměti. Narazí-li na definici funkce, vytvoří objekt typu funkce, uloží jej někde do paměti a opět si poznamená, že toto jméno odpovídá tomuto objektu.
Místo, kam se poznamenává vazba jména a objektu se nazývá jmenný
prostor (v anglické terminologii namespace). Každé přiřazení či definice
vytváří položku ve jmenném prostoru. Příkazem del
se položka ze
jmenného prostoru ruší. Zároveň každý objekt nese informaci o tom,
kolikrát je použit. V okamžiku, kdy je zrušen poslední odkaz na objekt,
je z paměti uvolněn i příslušný objekt.
Počet odkazů na objekt je možné zjistit pomocí funkce ref()
,
jednoznačný identifikátor objektu je možné zjistit pomocí funkce
id()
.
Uvažujme následující kousek programu
>>> r = [ 1, 2, 3, 4, 5 ]
>>> s = [ 1, 2, 3, 4, 5 ]
>>> t = r
Seznamy nazvané r
a s
jsou dva různé objekty, jména r
a
t
jsou dvě různá jména pro tentýž objekt. Proto se jakákoliv změna
v seznamu t
projeví i v seznamu r
.
>>> r.append(':-)')
>>> s
[1, 2, 3, 4, 5]
>>> t
[1, 2, 3, 4, 5, ':-)']
Je dokonce možné vytvářet rekurzivní objekty:
>>> r = range(5)
>>> r.append(r)
Posledním prvkem seznamu r
je teď seznam r
. Takovéto věci
je ale vhodné dělat až v okamžiku, kdy přesně víme, co děláme. Při
hodně nešikovném používání je možné zacyklit datové struktury tak, že
počítání odkazů přestane fungovat a v paměti mohou zůstávat obsazené
nepoužívané bloky.
OTOH: V okamžiku, kdy člověk začne potřebovat rekurzivní datové struktury, už většinou přesně ví, co dělá.
Každý soubor má vlastní globální jmenný prostor. Patří do něho všechny objekty, které byly vytvořeny na nejvyšší úrovni. (Na nejvyšší úrovni nemyslím na úrovni vlády, ale bez jakéhokoliv odsazeni :-). Kromě toho při vstupu do libovolné funkce se vytváří lokální jmenný prostor.
Na nejvyšší úrovni se pro zápis i pro čtení používá zapisuje do globálního jmenného prostoru. Příkazy, které se provádí z promptu jsou prováděny v globálním jmenném prostoru. Při volání funkce se vytváří lokální jmenný prostor. Všechny nově vytvářené objekty se vytváří v lokálním jmenném prostoru. Při hledání objektu se nejprve projde lokální jmenný prostor a až poté globální jmenný prostor.
>>> l = [ 'globalni' ]
>>> def f():
... l = ['lokalni']
...
>>> f()
>>> l
['globalni']
Ale pozor, pokud jsou objekty modifikovány, modifikace se provádí tam, kde jsou objekty definovány.
>>> l = [ 'globalni' ]
>>> def f():
... l.append('lokalni')
...
>>> f()
>>> l
['globalni', 'lokalni']
Je-li ve funkci potřeba modifikovat globální prostor jmen, je možné
použít direktivu global
se jmény objektů, které budou přiřazeny do
globálního jmenného prostoru.
>>> def f():
... global s
... s = 'lokalne zapsano'
...
>>> f()
>>> s
'lokalne zapsano'