[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