[python] globální proměnné

p.kosina gen2n na seznam.cz
Pondělí Leden 3 15:42:16 CET 2005


Děkuji za vyčerpávajjící vysvětlení.
Nechci vypadat jako Tlučhuba :-), přesto zkusím ještě jednou můj postoj.

class G:
   pass

g=G()
g.x=30

Možná nepoužívám nejsprávnější terminologii, když  nazývám x globální 
proměnnou (ano, je to lokální uvnitř G), nicméně objekt 'g.x' je 
"veřejně přístupný", *ze všech funkcí měnitelný bez jakýchkoliv dalších 
fíglu v rámci celého programu*, jedná se tedy, podle mne, o mnou 
obhajovanou superglobalni (superglobalni z hlediska celého programu a ne 
jednotlivé třídy či instance - z jejich hlediska to je samozřejmě 
lokální) proměnnou. Ale i výraz veřejně přístupný je OK, nic to na věci 
nemění. Možná se pletu, možná existují skulinky, kdy to neplatí, nicméně 
v programu s pár funkcemi a jednou main to funguje.

Uznávám, není to čisté řešení, přesto mi to připadá "čistější" než 
použití global. Také si vlastně uvědomuji, že nikdo zde neříkal, že to 
nefunguje, "jen" že to není globální proměnná.

Když ukazujete "zjednodušování" kódu vypouštěním funkcí f() i r(), tak 
to nevyjadřuje praxi. V praxi samozřejmě funkce takto jednoduché nejsou 
a nedají se vypustit, protože "něco dělají" a veřejně přístupné proměnné 
jsou tam jenom pro usnadnění práce (funkce tam není samoúčelně, kvůli 
nim), pro zpřehlednění kódu, pro přiblížení se práce v OOP. Snad 
klasickým případem je vznik nových proměnných ve funkci, které však je 
třeba si uchovat do dalšího průchodu funkcí,kde se s nimi bude opět 
pracovat.

Já si tedy OOP dost zjednodušuji, třebas když se vytváří nějaký textový 
editor v OOP, tak vlastně celý program je jedna velká třída a uvnitř ní 
jsou její proměnné 'self.x' viditelné ze všech jejích metod. Tomu jsem 
se právě chtěl svým přístupem přiblížit.


Pavel




Petr Prikryl napsal(a):
> p.kosina napsal...
> 
>>Připadá mi to nespravedlivé :-), že u OO se globální
>>proměnné vytváří naprosto transparentně self.x=10 v
>>kterékoliv metodě a platnost (včetně změn) je napříč celou
>>třídou a ještě je to vydáváno za velké plus.
> 
> 
> V tomto případě nejde ani o globální proměnnou, ani o
> proměnnou platnou v kterékoliv metodě třídy. Vytváří se v
> rámci objektu a je platná pouze v rámci objektu (instanci
> třídy). Na self.x není nic globálního ani magického. Můžu si
> to do češtiny přeložit jako "moje vlastní x", kdy "moje
> vlastní" uvažujeme z pohledu objektu samotného.
> 
> 
>>Naproti tomu u nás, u proceduráků, u nás je global, které se
>>však musí objevovat jednak v každé funkci zvlášť, což je
>>velmi netransparentní a ještě je to zavrženíhodné. Dá se to
>>samozřejmě obcházet, ale transparentnost je vždy přednost.
>>Funkce se dají samozřejmě volat s parametry a také vracet
>>výsledky, ale pokud je argumentů více, program se stává
>>zbytečně nepřehledným.
> 
> 
> Pokud bych chtěl, aby všechny proměnné byly globální, dostal
> bych se do počítačového pravěku. Programy pouze s globálními
> proměnnými by byly při současném rozsahu kódu nečitelné a
> neudržovatelné. Proto se ve funkcích vždy vytváří nové
> lokální proměnné. U jazyků, kde se proměnná musí povinně
> deklarovat (například Pascal) něco takového jako klíčové
> slovo "global" nepotřebuji -- lokální proměnná stejného
> jména má vždy přednost. Pokud není definována, bere se
> automaticky proměnná "globálnější".
> 
> Používání globálních proměnných u složitějších programů vede
> k vytváření závislostí, kdy jeden úsek kódu může nečekaným
> způsobem ovlivnit jinak naprosto nesouvisející jiný úsek
> kódu.
> 
> Souhlasím s tím, že špatný objektový návrh může být
> nepřehlednější, než dobrý procedurální návrh. Ale dobrý
> objektový návrh bude vždy udržovatelnější a přehlednější,
> než procedurální návrh. Jedinou nevýhodou může být vytváření
> více oddělených částí s kódem a daty (objektů), které se
> propojují vzájemnými odkazy (tj. zvýšení stupně nepřímosti
> odkazů). Na druhou stranu právě tento rys vynucuje čistší
> rozhraní, snižuje vzájemné závislosti a usnadňuje budoucí
> údržbu. I když, všechno se dá sprasit ;-)
> 
> 
>>Chci uvést jednu z transparentnější metod (možná jsem
>>objevil objevené, ale já jsem dosud používal seznamy nebo to
>>hrozné global):
>>
>>class globalniTrida:
>>   pass
>>
>>def r():
>>   Global.delka=10
>>
>>Global=globalniTrida()
>>r()
>>Global.delka=Global.delka+20
>>print Global.delka
>> >>> 30
> 
> 
> Následující příklad je významově naprosto shodný:
> 
> globalni_promenna = 10
> globalni_promenna = globalni_promenna + 20
> print globalni_promenna
> 
> Výše uvedenou třídou globalniTrida a vytvořením její
> instance Global se pouze zavede něco jako prostor jmen.
> Pokud si zavedu svůj modul -- soubor Global.py takto...
> 
> Global.py
> ------------------------------------------------------
> delka = 10
> ------------------------------------------------------
> 
> .... pak můžu ve svém programu psát:
> 
> import Global
> 
> Global.delka = Global.delka + 20
> print Global.delka
> 
> Definice a použití funkce r() a použití třídy do toho nic
> nového nevnáší. Je to jen krkolomě zapsané vytvoření
> inicializace proměnné uvnitř existujícího objektu.



Další informace o konferenci Python