Kezdőoldal » Számítástechnika » Programozás » Fuggveny globalis valtozo...

Fuggveny globalis valtozo pythonban mikor kell?

Figyelt kérdés

Pelda:


a = 10


def demo():

    global a

    print a



Eszrevettem, hogy nehol ott is elerheto a globalis valtozo a programomban ha elhagyom a global kulcsszot. De nem mindig, van ahol kotelezo megadnom hogy global. Mitol fugghet ez?



2015. márc. 25. 10:47
 1/4 anonim ***** válasza:
Akkor próbáld ki a globallal meg anélkül is, hogy a demo függvényben adsz az a-nak egy új értéket, és a függvényből való visszatérés UTÁN kiíratod.
2015. márc. 25. 12:07
Hasznos számodra ez a válasz?
 2/4 anonim ***** válasza:
Ha csak olvadod a változót, akkor elhagyhatod.
2015. márc. 25. 15:55
Hasznos számodra ez a válasz?
 3/4 Ozmium42 ***** válasza:
A függvényen belül a hívott változó alapból lokális, vagyis ha itt módosítasz rajta, az a függvényen kívüli (azonos nevű) globális változót nem érinti. Akkor kell globálissá tenni tenni a lokális változót, ha azt akarod, hogy a módosítás a "külső" globális változóra is kiterjedjen.
2015. márc. 26. 12:21
Hasznos számodra ez a válasz?
 4/4 anonim ***** válasza:

Alapból a Python "névterek"-ből (namespace) áll és ezekben a névterekben találhatóak a változók, függvények, osztályok, stb, amik önmagában szintén saját névtereket képeznek.


Amikor azt írod hogy "a = 10", akkor a jelenlegi névtérben létrehozol (vagy felülírsz) egy "a" nevű változót (nevet) és 10-et adsz meg neki értéknek. Az "a" értéke sosem módosul, hanem felülíródik minden értékadásnál, mert a "=" operátor mindig új nevet hoz létre, így pl. overloadolni sem lehet azt.


Ha a demo függvényben (névtérben) azt írod hogy "a = 5" akkor a demo névtérben létrehoz egy "a" nevű változót. Ha te a globális névtérben akarod inkább használni az "a" változót akkor ezt meg kell mondani a programnak: ne a lokális névtérben hozd létre, hanem a globálisban. Erre való a global parancs.


Tehát itt 2 "a" változód lesz, egy lokális a demo névtérben és egy globális, az egyik 5 értékkel, a másik 10-el:


a=10

def demo():

__a=5


Itt viszont csak egy "a" változód (neved) lesz, a globális névtérben, 5 értékkel:


a=10

def demo():

__global a

__a=5


Az oka hogy elhagyhatod a global szót az az, hogy ha nem létrehozol el nevet értékadással hanem egy létezőre hivatkozol, akkor elkezdi keresni a program, hogy melyik névtérben lehet a hivatkozott név:


a = 10

def demo1():

__def demo2():

____print a


Itt a globális névtérben van egy "a" változó és a "demo1" függvény, aminek a névterében van egy "demo2" függvény ahonnan hivatkozunk az "a"-ra. Megnézi hogy a demo2-ben van e "a", mivel nincs, kijjebb lép, megnézi a demo1-ben hogy van e "a", nincs ezért még kijjebb lép, megnézi hogy a globális névtérben van e "a", van ezért azt használja.


Ha nem talál "a" nevet és már nem tud kijjebb lépni, "NameError" kivételt fogsz kapni, azaz nincs definiálva ilyen név.


Vigyázz, mert ha a demo1-ben is van "a", akkor arra fog hivatkozni és nem a globálisra, mert az "közelebb" van. Ha a globálist akarod használni helyette, akkor akkor itt is szólni kell a global kulcsszóval!


Python3-ban létezik egy olyan kulcsszó is hogy nonlocal.

Ez olyan mint a global, csak nem a global névtérben fogja módosítani (felülírni) a kérdéses nevet, hanem el kezdi keresni a nevet a lokális névterekben a fentebb vázolt módon és az első találatra fog hivatkozni.


Nem kell definiálni egy nevet a globális névtérben ahhoz hogy használhassuk a global kulcsszót.


a = 10

pontosan ugyan azt csinálja mint a

def demo():

__global a

__a = 10

demo()

azaz a globális névtérben létrehoz egy "a" nevet (és hozzáköti a 10-et).


Ha kíváncsi vagy a névterekre amúgy a dir() parancs listázza:

dir():

['__builtins__', '__doc__', '__name__', '__package__', 'a', 'demo1']


dir(a):

['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']


Lehet látni hogy az "a" nem csak változó hanem névtér is, és vannak függvényei amik szintén névtereket alkotnak (és minden függvénynek van __call__ névterük ami meghívódik ha meghívjuk a függvényt):


>>> a = 10

>>> a.__add__(3) #ez történik valójában amikor azt írjuk hogy a + 3

13


És ha korrektek akarunk lenni, akkor azt is el kell mondani hogy fentebb az történt hogy az "a" névhez kötöttük a 10 int típusú objektumot (névteret), tehát nem az "a" képzi a névteret, csak csak egy név, egy kötelék amivel hivatkozni lehet a hozzákötött névtérre. A névtér valójában maga az objektum: dir(10)


Csak azért írtam le ilyen hosszan mert sok kezdő beleesik abba a hibába hogy azt hiszik, a Python ugyan úgy működik mint a többi programozási nyelv (pointerek, változók, referenciák stb itt nem léteznek!) és ebből jönnek a bajok, nem értik később miért nem azt csinálja a program amit szerintük kéne. Jó ha az ember tisztában van a névterekkel és a Python működésével.

2015. márc. 26. 21:55
Hasznos számodra ez a válasz?

Kapcsolódó kérdések:




Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!