Seite 1 von 1

scope bei lokalen funktionsdefinitionen

Verfasst: Mittwoch 27. September 2006, 12:11
von behe0815
Hallo!

Folgender code gibt 'muh' aus, ich hatte gerne 'hum' :P

Code: Alles auswählen

def test():
	a = 0
	
	def f1():
		a = 1
		return
	
	def f2():
		if (a == 1):
			print 'hum'
		else:
			print 'muh'
		return

	f1()
	f2()
	
	return
	
test()
Wie kann ich f1() und f2() dazu bringen, die in test() deklarierte variable a zu verwenden, und nicht eine eigene variable a lokal anzulegen?

Geht das ueberhaupt? Konkret will ich in test() lokal einige funktionen definieren, die ich einem expat xml parser uebergebe. Diese funktionen sollen aber auf lokale variablen von test() zugreifen koennen.

Behe0815

Verfasst: Mittwoch 27. September 2006, 12:16
von Monk
Einfach global benutzen...

Code: Alles auswählen

def test(): 
    a = 0 
    
    def f1(): 
        global a
        a = 1 
        return 
    
    def f2(): 
        global a
        if (a == 1): 
            print 'hum' 
        else: 
            print 'muh' 
        return 

    f1() 
    f2() 
    
    return 
    
test() 
Ergebnis:

Code: Alles auswählen

>>> hum
Gruß, der Monk

Verfasst: Mittwoch 27. September 2006, 12:26
von Nirven
Lieber so, auf global verzichten wenn es geht.

Code: Alles auswählen

def test():
    a = 0
   
    def f1(a):
        
        a = 1
        return a
   
    def f2(a):
        
        if (a == 1):
            print 'hum'
        else:
            print 'muh'
        return

    a = f1(a)
    f2(a)
   
    return
   
test()

Verfasst: Mittwoch 27. September 2006, 13:40
von Monk
Geht nur leider nicht, wenn er Callback-Funktionen für eine externe API (expat) definiert. Da muss dann doch global her, oder...

Code: Alles auswählen

class CallBackHost:
    def __init__(self):
        self.a = 0

    def f1(self):
        self.a = 1

    def f2(self):
        if (a == 1): 
            print 'hum' 
        else: 
            print 'muh' 
        return 
        
if __name__ == "__main__":
    c = CallBackHost()
    c.f1()
    f = c.f2
    # f wird uebergeben und folgende Zeile
    # von der externen API ausgefuehrt
    f()
Wenn Du alles in eine Klasse einbettest, hast Du genau die benötigte Funktionalität ohne globale Variablen. Der Parameter self wird durch die Bindung an c automatisch vom Interpreter übergeben.

Gruß, der Monk

Verfasst: Mittwoch 27. September 2006, 14:04
von behe0815
Danke fuer die Tipps, "global" war mir bis dato unbekannt, hat aber leider in meinem realen Sourcecode nicht funktioniert. Keine Ahnung warum.

Aber mit der Hilfsklasse, wie sie Monk vorgeschlagen hat, funktioniert es ohne Probleme. Also sind in Python Klassenmethoden ebenso wie normale Funktionen als Callbacks verwendbar. Das ist doch mal gut zu wissen.

Nochmals tausend Dank. :D

Verfasst: Mittwoch 27. September 2006, 18:18
von mitsuhiko
behe0815 hat geschrieben:Danke fuer die Tipps, "global" war mir bis dato unbekannt, hat aber leider in meinem realen Sourcecode nicht funktioniert. Keine Ahnung warum.
Wäre auch besser es funktioniere nicht. Das ist grob fahrlässig. Und ganz sicher nicht Thread safe... :roll:

probiers so:

Code: Alles auswählen

def foo():
 ns = {'a': 42}
 def inc():
  ns['a'] += 1
 def prr():
  print ns['a']
 inc()
 inc()
 inc()
 prr()

foo()

Verfasst: Mittwoch 27. September 2006, 18:27
von birkenfeld
... und ich darf noch anmerken, dass "return" am Ende einer Funktion ziemlich sinnfrei ist.