/ / Arbeiten mit einer globalen Variablen innerhalb einer Python-Funktion - Python

Arbeiten mit einer globalen Variablen innerhalb einer Python-Funktion - Python

In diesem Code-Snippet:

def taylorVazquez(fx,a,b,n,puntos):

puntosX = linspace(a,b,num=puntos)
aproxY = []
puntosY = []

def toFloat():
puntosX = [float(x) for x in puntosX]
aproxY = [float(y) for y in aproxY]
puntosY = [float(y) for y in puntosY]

Ich bekomme die Fehlermeldung:

UnboundLocalError: local variable "puntosX" referenced before assignment

Und so weiß ich, dass es den anderen beiden Variablen auch passieren würde. Was kann ich machen das ist das Äußere taylorVazquez"s Variablen, die ich an der inneren Funktion manipuliere, mit anderen Worten, ich möchte, dass die Zuweisungen auch für den äußeren Bereich funktionieren

Antworten:

2 für die Antwort № 1

Immer wenn Sie einer Variablen in a einen Wert zuweisenIn diesem Bereich wird angenommen, dass die Variable lokal ist. Je nachdem, welches Python Sie verwenden, müssen Sie entweder nichtlokal (Python 3) verwenden oder die Werte mit den Parametern (Python 2) übergeben.

Hier ist Python 2:

def toFloat(puntosX, aproxY, puntosY):  # now the names of the enclosing function can be passed to the toFloat function
puntosX = [float(x) for x in puntosX]
aproxY = [float(y) for y in aproxY]
puntosY = [float(y) for y in puntosY]

Im Python 3:

def toFloat():
nonlocal puntosX, aproxY, puntosY  # the names now refer to the enclosing scope rather than the local scope
puntosX = [float(x) for x in puntosX]
aproxY = [float(y) for y in aproxY]
puntosY = [float(y) for y in puntosY]

global werden NICHT Arbeiten Sie in dieser Situation, da Sie auf die Namen einer einschließenden Funktion verweisen.

Eine weitere Sache, Sie können versuchen, neue zuzuweisenWerte auf die Namen im einschließenden Bereich. Ihre derzeitige Taktik funktioniert nicht, da Sie diesen Namen innerhalb der innersten Funktion neue Objekte zuweisen. (Listenverstehen erstellen neue Listen.) Wenn Sie die neuen Werte beibehalten müssenSie müssen diese Werte (zum Beispiel) an den umschließenden Bereich zurückgeben und Ihre ursprünglichen Namen den neuen Werten zuweisen. Zum Beispiel in Python 2:

def taylorVazquez(fx,a,b,n,puntos):
puntosX = linspace(a,b,num=puntos)
aproxY = []
puntosY = []

def toFloat(puntosX, aproxY, puntosY):  # now the names of the enclosing function can be passed to the toFloat function
puntosX = [float(x) for x in puntosX]
aproxY = [float(y) for y in aproxY]
puntosY = [float(y) for y in puntosY]
return puntosX, aproxY, puntosY

puntosX, aproxY, puntosY = toFloat(puntosX, aproxY, puntosY)  # now you can reassign these names to the new values

nicht wie globalSie können diesen Namen keine neuen Werte zuweisen und sie für den einschließenden Bereich gelten lassen.


2 für die Antwort № 2

Wenn Sie eine Variable in einer Python-Funktion zuweisen,Der Interpreter geht davon aus, dass es sich um eine lokale Variable handelt. Bei allen anderen Verwendungen dieser Variablen wird auch davon ausgegangen, dass sie lokal sind, auch wenn sie vor der Zuweisung liegen. Deshalb erhalten Sie eine Ausnahme local variable "puntosX" referenced before assignment.

Es gibt einige mögliche Lösungen.

Eine ist, die Variable als zu deklarieren global (oder in Python 3, nonlocal wenn es sich um eine lokale Variable in einer einschließenden Funktion handelt).

def taylorVazquez(fx,a,b,n,puntos):

puntosX = linspace(a,b,num=puntos)
aproxY = []
puntosY = []

def toFloat():
nonlocal puntosX, aproxY, puntosY # this fixes the UnboundLocalError

puntosX = [float(x) for x in puntosX]
aproxY = [float(y) for y in aproxY]
puntosY = [float(y) for y in puntosY]

Eine andere Möglichkeit besteht darin, die Variable an Ort und Stelle zu mutieren, anstatt sie neu zuzuweisen. Zum Beispiel können Sie verwenden list.append und list.__setitem__ auf einer Liste, ohne jemals einen lokalen Verweis darauf zu machen.

def toFloat():
for i, v in enumerate(puntosX):
puntosX[i] = float(v) # this calls puntosX.__setitem__, mutating it in place

# etc...

Eine letzte Option besteht darin, Ihre Funktionen zu testen und Argumente zu übergeben und Werte zurückzugeben, anstatt sich auf die verschachtelten Namespaces zu verlassen, um Ihre Werte verfügbar zu machen. Zum Beispiel:

def toFloat(lst):
return [float(v) for v in lst]

# then later
puntosX = toFloat(puntosX)

1 für die Antwort № 3

Sie können auf die Variable gut zugreifen, das Problem hier ist, dass es in Python2 keine Möglichkeit gibt, die Variable neu zuzuweisen. Es gibt ein PEP, um dieses Problem zu beheben (PEP-227).

Es wurde tatsächlich in Python 3 angesprochen, und Sie konnten Ihre Variablen als bezeichnen nonlocal, aber das ist kein großer Komfort, wenn Sie noch Python 2 verwenden.

Sie können dies umgehen, indem Sie Folgendes tun:

def f1():
x = [1]
def f2():
x[0] = 2
f2()
print x[0]
f1()

Es gibt auch eine Reihe anderer potenzieller Problemumgehungen, aber die meisten von ihnen führen zu unerwartetem Verhalten.