Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correctness about variable scope

Tags:

python

scope

I'm currently developing some things in Python and I have a question about variables scope.

This is the code:

a = None
anything = False
if anything:
    a = 1
else:
    a = 2

print a # prints 2

If I remove the first line (a = None) the code still works as before. However in this case I'd be declaring the variable inside an "if" block, and regarding other languages like Java, that variable would only be visible inside the "if".

How exactly variable scoping works in Python and what's the good way to program in cases like this?

Thanks!

like image 826
Menda Avatar asked Mar 01 '10 22:03

Menda


2 Answers

As a rule of thumb, scopes are created in three places:

  1. File-scope - otherwise known as module scope
  2. Class-scope - created inside class blocks
  3. Function-scope - created inside def blocks

(There are a few exceptions to these.)

Assigning to a name reserves it in the scope namespace, marked as unbound until reaching the first assignment. So for a mental model, you are assigning values to names in a scope.

like image 149
Shane Holloway Avatar answered Sep 24 '22 23:09

Shane Holloway


I believe that Python uses function scope for local variables. That is, in any given function, if you assign a value to a local variable, it will be available from that moment onwards within that function until it returns. Therefore, since both branches of your code are guaranteed to assign to a, there is no need to assign None to a initially.

Note that when you can also access variables declared in outer functions -- in other words, Python has closures.

def adder(first):
    def add(second):
        return first + second

    return add

This defines a function called adder. When called with an argument first, it will return a function that adds whatever argument it receives to first and return that value. For instance:

add_two = adder(2)
add_three = adder(3)
add_two(4) # = 6
add_three(4) # = 7

However, although you can read the value from the outer function, you can't change it (unlike in many other languages). For instance, imagine trying to implement an accumulator. You might write code like so:

def accumulator():
    total = 0
    def add(number):
        total += number
        return total
    return add

Unfortunately, trying to use this code results in an error message:

UnboundLocalError: local variable 'total' referenced before assignment

This is because the line total += number tries to change the value of total, which cannot be done in this way in Python.

like image 35
Michael Williamson Avatar answered Sep 24 '22 23:09

Michael Williamson