2012-04-22 12 views
12

Gegeben:python: Wie erfasse ich eine Variable, die in einem nicht globalen äußeren äußeren Bereich deklariert wurde?

def f(): 
    x = 0 
    def g(): 
     h() 
    def h(): 
     x += 1 
     print(x) 
    g() 

>>> f() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 8, in f 
    File "<stdin>", line 4, in g 
    File "<stdin>", line 6, in h 
UnboundLocalError: local variable 'x' referenced before assignment 
>>> 

Wie kann ich h sehen die x variabel zu machen?

Danke.

EDIT

es bereits erwähnt haben sollte, ich bin mit Python 2.7.3

+0

wie fast scheint genannt -Global für mich ... schlechte Idee? (aber immer noch gute Frage) – Shep

+0

@Shep: Sie wollen ein anderes x für jeden Aufruf f(), so dass eine globale Variable nicht tun würde. – EOL

Antwort

11

Sie x eine function attribute machen können:

def f(): 
    f.x = 0 
    def g(): 
     h() 
    def h(): 
     f.x += 1 
     print(f.x) 
    g() 

Auch Ab Python 3 können Sie das Schlüsselwort nonlocal verwenden.

+3

+1 Schöne Lösung. –

+3

Wenn Sie es an 'g' oder' h' anhängen, erhalten Sie für jeden Aufruf von 'f' ein separates' x' anstatt eines globalen, das Bereiche wie 'f' und somit wahrscheinlich global ist. Das ist besonders wichtig, wenn "g" oder "h" als Verschlüsse enden (sogar indirekt, beispielsweise indem sie als Rückruf hinzugefügt werden). – delnan

5

Wenn Sie Python verwenden 3, verwenden Sie das Schlüsselwort nonlocal. Setzen Sie nonlocal x am Anfang der Funktion h. Wenn Sie Python 2.x verwenden, macht eine Abhilfe x eine Liste mit einem Element, so können Sie es ändern:

def f(): 
    x = [0] 
    def g(): 
     h() 
    def h(): 
     x[0] += 1 
     print x[0] 
    g() 

f() 
4

In Python 3 verwenden nur nonlocal:

def f(): 
    x = 0 
    def g(): 
     h() 
    def h(): 
     nonlocal x 
     x += 1 
     print(x) 
    g() 
f() 
+1

Funktioniert nur in Python 3 – jamylak

+0

Er verwendet print() bedeutet, dass das OP nur Python 3.x verwendet. –

+0

Es ist erwähnenswert. Aber 'print()' mit einem Argument funktioniert tatsächlich auf Python 2, obwohl ich auch zustimme, dass er Python 3 verwendet. – jamylak

0

Können wir setzen nicht x als Funktionsargumente als Abhilfe

def f(): 
    x = 0 
    def g(): 
     h(x) 
    def h(x): 
     x += 1 
     print(x) 
    g() 

f() 
0

Einfachste ist es, ein dict oder leere Klasse zu verwenden, zB:

class Empty: 
    x = 0 

def f(): 
    closure1 = dict(x=0) 
    closure2 = Empty() 
    def g(): h(x) 
    def h(x): 
     closure1["x"] += 1 
     closure2.x += 1 
    g() 
    print closure1["x"], closure2.x 

Obwohl viele gute Lösungen bereits zur Verfügung gestellt wurden, th ey haben Eckfällen:

  • nonlocal, pro Ashwini, nur Python 3.x Attribut
  • Funktion ist, pro ovgolovin, wird fehlschlagen wird f neu definiert wird und später unter Bezugnahme
Verwandte Themen