Dotaz: Statické proměnné ve funkcích

>> jsem amatérský začátečník v programování, jak v pythonu, tak
>> v C, z toho důvodu bych potřeboval objasnit tuto věc: je možné
>> v pythonu užívat proměnnné na způsob statických proměnných funkcí
>> jazyka C ? - tedy proměnná se ve funkci inicializuje jen
>> jednou a drží si mezi voláním funkce svou hodnotu.

Odpověď

Ne. Vyplývá to z odlišností kompilovaného a interpretovaného jazyka. Zatímco v kódu vygenerovaném z céčkové funkce může být pevně zakompilovaná adresa paměťového místa, které udržuje obsah statické proměnné, v pythonovském kódu se proměnné realizují v dynamicky přidělovaném prostoru a zpřístupňují se přes odkazy (obvykle pojmenované).

Prostor proměnných se člení na globální (v rámci jednoho modulu) a lokální (pro bloky kódu). Pro důkladnější studium doporučuji podkapitolu "4.1 Naming and binding" ze standardní pythonovské dokumentace.

Uvedený rys by tedy bylo možné realizovat použitím globální proměnné, což ale není totéž. Navíc se to spíš nedoporučuje. Doporučuji dobře zvážit, jestli se vůbec má něco jako statická proměnná chtít používat.

Další možnosti realizace záměru závisí na charakteru požadované funkce. Podobný obrat lze asi nejobecněji a docela čistě nasimulovat pomocí instance třídy (tj. objektu), který v sobě udržuje požadovanou proměnnou. Kromě toho tento objekt definuje metodu (členskou funkci), která realizuje požadovanou funkčnost.:

class C:

   def __init__(self):
       self.x = 10

   def fce(self, a):
       self.x = self.x + a
       return self.x

c = C()

Aby vše fungovalo stejně, jako v případě céčkové funkce se statickou proměnnou, musí se volat odpovídající metoda stále toho stejného objektu.

>>> print c.fce(1)
11
>>> print c.fce(1)
12
>>> print c.fce(10)
22
>>> print c.fce(10)
32
>>> print c.fce(10)
42
>>> print c.fce(10)
52

Abychom na to nemuseli pořád myslet, můžeme si volání metody tohoto objektu pojmenovat. Pak bude zápis vypadat podobně, jako by tomu bylo v C:

>>> mojeFunkce = c.fce
>>> print mojeFunkce(1)
53
>>> print mojeFunkce(1)
54
>>> print mojeFunkce(10)
64
>>> print mojeFunkce(10)
74
>>> print mojeFunkce(10)
84
>>> print mojeFunkce(10)
94

Zajímavou možností, která se dá použít ve speciálnějším případě, kdy funkci nechceme při volání předávat vstupní parametry, je využití takzvaných generátorů. Z opačného pohledu by se dalo říci, že pythonovské generátory by se v C daly napodobit funkcí se statickou proměnnou (ale ne zcela obecně).