Edit detail for StatickePromenneVeFunkcich revision 1 of 1

1
Editor: pycz
Time: 2006/10/10 14:00:11 GMT+0
Note:

changed:
-
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ě).




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