Jelikož jsem na toto téma nedávno narazil při diskusi s mým spolubydlícím a také se pravidelně objevuje v předmětech prof. Hrušky :), tak jsem se rozhodl osvětlit část problematiky přístupu ke globálním proměnným v jazycích Python a PHP.
Nejdříve začneme s Pythonem (v PHP je situace podobná -- popíšu později). Představte si, že máte následující fragment kódu, kde x
je proměnná na nejvyšší úrovni (globální) a foo()
je funkce, ve které chcete změnit hodnotu globální proměnné x
:
x = 4 def foo(): x = 5 print(x) foo() print(x)
Na první pohled to vypadá pěkně. Jakmile si ale tento kód spustíte, tak místo vypsání 4 a 5 dojde k vypsání dvou čtyřek... V čem je problém? V Pythonu (stejně jako třeba v PHP) se proměnné nedeklarují/nedefinují explicitně, nýbrž implicitně při přiřazení hodnoty do proměnné (na rozdíl např. od C++ či Javy). Jelikož parser nemá možnost jak vytušit, zda chcete přiřazovat do existující proměnné na globální úrovni, nebo chcete vytvořit lokální proměnnou pro funkci, tak volí druhou možnost (vede to k menšímu množství potenciálních problémů -- zkuste se zamyslet nad tím, proč tomu tak je). Tedy, místo přiřazení čísla 5 do globální proměnné x
se vytvoří lokální proměnná s hodnotou 5.
Fajn, ale jak to tedy vyřešit? Řešením je deklarace global, která dává překladači najevo, že chcete pracovat s existující proměnnou na globální úrovni a nechcete vytvářet lokální proměnnou. Níže uvedený fragment kódu bude již fungovat dle očekávání.
x = 4 def foo(): global x x = 5 print(x) foo() print(x)
V PHP je to obdobné:
$x = 4; function foo() { global $x; $x = 5; } echo $x; foo(); echo $x;
Na závěr bych chtěl upozornit na jeden rozdíl mezi Pythonem a PHP. Pokud v Pythonu budete globální proměnnou pouze číst, tak ji není třeba deklarovat pomocí global
(to se hodí především, pokud takto přistupujete ke "konstantám" -- nemusíte používat global
). Následující příklad vytiskne hodnotu 4.
x = 4 def foo(): print(x) foo()
V PHP je nutné i v tomto případě global
použít. Důvodem je to, že v PHP při pokusu o čtení neinicializované hodnoty dojde k automatické inicializaci této hodnoty na defaultní hodnotu (0, false, prázdný řetězec apod., dle kontextu). Následující příklad vytiskne prázdný řetězec :).
$x = 4; function foo() { echo $x; } foo();
Konstanty se v PHP dají definovat pomocí funkce define(). K těmto konstantám se pak dá přistupovat bez použití global
(mají superglobální platnost).
Závěr
V tomto příspěvku jsem se snažil vysvětlit důvod, proč v jazycích, jako je Python a PHP, existuje deklarace global
(která není v jazycích, jako je C++ či Java, potřeba).