Důvod použití deklarace global v Pythonu a PHP

Od Petr Zemek, 2009-12-12

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

Obsah tohoto pole je soukromý a nebude veřejně zobrazen.

Filtrované HTML (využíváno)

  • Povolené HTML značky: <a href hreflang> <em> <strong> <cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <table>
  • Zvýraznění syntaxe kódu lze povolit přes následující značky: <code>, <blockcode>, <bash>, <c>, <cpp>, <haskell>, <html>, <java>, <javascript>, <latex>, <perl>, <php>, <python>, <ruby>, <rust>, <sql>, <text>, <vim>, <xml>, <yaml>.
  • Řádky a odstavce se zalomí automaticky.
  • Webové a e-mailové adresy jsou automaticky převedeny na odkazy.
CAPTCHA
1 + 1 =
Vyřešte tento jednoduchý matematický příklad a vložte výsledek. Např. pro 1+3 vložte 4.
Nějak se mi tady rozmohl spam, takže poprosím o ověření.