Assigning to Variable from Parent Function: "Local Variable Referenced Before Assignment"

Assigning to variable from parent function: Local variable referenced before assignment

What you are seeing here is the difference between accessing and assigning variables. In Python 2.x you can only assign to variables in the innermost scope or the global scope (the latter is done by using the global statement). You can access variables in any enclosing scope, but you cannot access a variable in an enclosing scope and then assign to it in the innermost or global scope.

What this means is that if there is any assignment to a name inside of a function, that name must already be defined in the innermost scope before the name is accessed (unless the global statement was used). In your code the line c += 3 is essentially equivalent to the following:

tmp = c
c = tmp + 3

Because there is an assignment to c in the function, every other occurrence of c in that function will only look in the local scope for funcB. This is why you see the error, you are attempting to access c to get its current value for the +=, but in the local scope c has not been defined yet.

In Python 3 you could get around this issue by using the nonlocal statement, which allows you to assign to variables that are not in the current scope, but are also not in the global scope.

Your code would look something like this, with a similar line at the top of funcC:

   def funcB():
nonlocal c
c += 3
...

In Python 2.x this isn't an option, and the only way you can change the value of a nonlocal variable is if it is mutable.

The simplest way to do this is to wrap your value in a list, and then modify and access the first element of that list in every place where you had previously just used the variable name:

def funcA():
print "funcA"
c = [0]
def funcB():
c[0] += 3
print "funcB", c[0]

def funcC():
c[0] = 5
print "funcC", c[0]

print "c", c[0]
funcB()
funcC()
funcB()
funcC()
print "end"

funcA()

...and the output:

funcA
c 0
funcB 3
funcC 5
funcB 8
funcC 5
end

Local variable referenced before assignment?

When Python parses the body of a function definition and encounters an assignment such as

feed = ...

Python interprets feed as a local variable by default. If you do not wish for it to be a local variable, you must put

global feed

in the function definition. The global statement does not have to be at the beginning of the function definition, but that is where it is usually placed. Wherever it is placed, the global declaration makes feed a global variable everywhere in the function.

Without the global statement, since feed is taken to be a local variable, when Python executes

feed = feed + 1,

Python evaluates the right-hand side first and tries to look up the value of feed. The first time through it finds feed is undefined. Hence the error.

The shortest way to patch up the code is to add global feed to the beginning of onLoadFinished. The nicer way is to use a class:

class Page(object):
def __init__(self):
self.feed = 0
def onLoadFinished(self, result):
...
self.feed += 1

The problem with having functions which mutate global variables is that it makes it harder to grok your code. Functions are no longer isolated units. Their interaction extends to everything that affects or is affected by the global variable. Thus it makes larger programs harder to understand.

By avoiding mutating globals, in the long run your code will be easier to understand, test and maintain.

How can I avoid this variable referenced before assignment?

liA variable in b() function is never initialized.

So, you should edit the code in the followed way:

def a():
liA = []
def b(liA):
for i in liA:
i += 1
liB = generateList()
for i in liB:
i -= 1
liA = liB

def generateList():
return [1,2,3,4]

b(liA)

a()

Hope I helped you!

Local variable referenced before assignement

You're trying to assign to a global. Python makes you explicitly do that.

def progress_print(chunk):
global elapsed
elapsed += len(chunk)

In general this is a pretty good sign that you need to refactor your code until you don't need globals any more.

Note that assignment and access are different beasts - the former requires you to explicitly declare globals, the latter does not. Case in point, your total variable is another global but you do not attempt to assign to it, hence python does not complain.

The Programming FAQ goes into more detail:

What are the rules for local and global variables in Python?

In Python, variables that are only referenced inside a function are
implicitly global. If a variable is assigned a new value anywhere
within the function’s body, it’s assumed to be a local. If a variable
is ever assigned a new value inside the function, the variable is
implicitly local, and you need to explicitly declare it as ‘global’.

Though a bit surprising at first, a moment’s consideration explains
this. On one hand, requiring global for assigned variables provides a
bar against unintended side-effects. On the other hand, if global was
required for all global references, you’d be using global all the
time. You’d have to declare as global every reference to a built-in
function or to a component of an imported module. This clutter would
defeat the usefulness of the global declaration for identifying
side-effects.

Local variable referenced before assignment in Python

Due to this line count +=1 python thinks that count is a local variable and will not search the global scope when you used if count == 3:. That's why you got that error.

Use global statement to handle that:

def three_upper(s): #check for 3 upper letter
global count
for i in s:

From docs:

All variable assignments in a function store the value in the local
symbol table; whereas variable references first look in the local
symbol table, then in the global symbol table, and then in the table
of built-in names. Thus, global variables cannot be directly assigned
a value within a function (unless named in a global statement),
although they may be referenced.

Another local variable referenced before assignment - Python

You misspelled "conceded":

condeded_away = 0
^

Also, you may want to use a different data structure for final_stats, like a dictionary:

teams = {
'team1': [...],
'team2': [...],
...
}

You can then look up the stats for a team much more quickly:

stats = teams['team2']

Python showing local variable referenced before assignment

The previous answer is mostly correct. Python considers any variable that you directly change the value of to be a local variable. Since you write top += 1, top is directly modified inside push, and is a local variable to push. The variable stack, on the other hand, is not changed.

I consider the fact that Python considers += operators to cause a variable to become local to be a bit of a bug. But it's too ingrained in the language.

And yes, the correct solution is to use nonlocal.

If you removed the top += 1 line, your code wouldn't work, but top would refer to the outer variable.

python3 - decorator function: Variable referenced before assignment

There are few errors in your code:

def args_wrapper(*args, **kwargs):
request = json.loads(request.context)

You're using request.context while request variable is undefined (it will be defined only after json.loads(request.context) will be executed). You tried to fix it using request = json.loads(args[1].context), but got JsonContextRequest object is not subscriptable in wrapped function. Look at this line closer:

return func(*args, **kwargs)

You decorator returns wrapped function called with the same params, so this code result isn't used, you don't pass request and header to wrapped function:

request = json.loads(request.context)
request = request["request"]
header = request["headers"]

Also you shouldn't call wrapped function:

func(*args, **kwargs)

I guess you want to do something like this:

def json_and_error(func):
def args_wrapper(this, request):
context = request.context
request = json.loads(context)
request = request["request"]

return func(this, request, context)

return args_wrapper


Related Topics



Leave a reply



Submit