Working with a global variable inside a python function

In this 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]

I get an error message:

UnboundLocalError: local variable 'puntosX' referenced before assignment

And so I know that this will happen with two other variables. What can I do with external variables taylorVazquezwith the ones that I manipulate in an internal function, in other words, I want the tasks to also work for the external area.

+3
source share
3 answers

Whenever you assign a value to a variable in a given scope, the variable is considered local to that scope. Depending on which Python you are using, you need to either use non-local (Python 3) or pass values ​​when using parameters (Python 2).

Here is 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]

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 , .

, . , . ( .) , () . , 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

global, .

+2

Python, , . , , . local variable 'puntosX' referenced before assignment.

.

global ( Python 3, nonlocal, ).

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]

- , . , list.append list.__setitem__ , .

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

    # etc...

- , , . :

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

# then later
puntosX = toFloat(puntosX)
+2

, , Python2 . PEP (PEP-227).

It was actually addressed in Python 3, and you could label your variables as nonlocal, but this is not a huge comfort if you are still using Python 2.

You can get around this by doing something like this:

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

There are also a number of other possible workarounds, but most of them will lead to unexpected behavior.

+1
source

All Articles