Skip to content Skip to sidebar Skip to footer

How Scope Is Determined In Python

Why does the first print statement in the second function throw an error that x is not defined? x = 5 def function_a(): print(x) def function_b(): print(x) x = 7

Solution 1:

Python will infer and use the variable from the inner scope whenever it sees the variable declared within the scope, even if that variable is declared after usage.

To demonstrate this, I created two scenarios.


Variable declared inside the inner scope

A variable is inferred in the following order: local, nonlocal, and global. Since x is declared inside the inner scope, Python will infer and use the x in this scope even if it is declared after usage.

Note that Python cannot distinguish modification from declaration; what was meant to modify x from the global scope was interpreted to declare another variable x within that scope.

Inferred Inner

No variables declared inside the inner scope

If no variables are declared within the inner scope, Python will switch the inferred scope to nonlocal, and then to global.

Inferred Global

Explicitly switching scope

If you explicitly declared the scope of x beforehand, Python would not have to infer.

Declared Global

The following code will not throw an error because the scope it uses is explicitly the global scope instead of the inner one.

x = 5defscope():
    global x
    print(x)
    x = 7print(x)

Scopes

By choosing which scope to work with, you are not only using the variables within that specific scope but also modifying the variables. Therefore, you need extra caution when dealing with scopes.

Because Python cannot distinguish variable declaration from variable modification, my advice is that if you want to use a global variable, you should explicitly state it beforehand.

This also applies to nested scopes.

x = 5defouter():
    x = 7definner():
        nonlocal x
        print(x)
        x = 3print(x)
    
    inner()

Running the outer function gives the following result.

>>> outer()
73

Try changing the nonlocal keyword to global and see a different result; or remove the line completely to get an error.

Solution 2:

In the 2nd method, you have written x = 7, which makes x a local variable for that method. But since, you are trying to access it on the print statement before the line "x = 7", it throws an error saying local variable x is accessed before assignment.

If you remove the line x = 7, it would work just fine. You can try this

x = 5defvs_code():
    print(x)

defvs_code1():
    print(x)
    y = 7print(y)

this will print 5 5 7

Now, since I am not declaring x inside 2nd method, now x is not local for 2nd method. If you declare it inside 2nd method, it will interpret that as a local variable. and you have to use it only after assignment.

Hope you understood.

Solution 3:

python is special in variable scope

you can use dis module to see what happeded.

deffoo():
    print(x)
    print(y)
    x = ...
import dis
dis.dis(foo)

output

20 LOAD_GLOBAL              0 (print)
              2 LOAD_FAST                0 (x)
              4 CALL_FUNCTION            16 POP_TOP

  38 LOAD_GLOBAL              0 (print)
             10 LOAD_GLOBAL              1 (y)
             12 CALL_FUNCTION            114 POP_TOP

  416 LOAD_CONST               1 (Ellipsis)
             18 STORE_FAST               0 (x)
             20 LOAD_CONST               0 (None)
             22 RETURN_VALUE

x is LOAD_FAST

y is LOAD_GLOBAL before running, python thinks x is a local variable because you try to modify it (cannot modify global variable).

this will works fine

defvs_code1():
    global x
    print(x)
    x = 7print(x)

Solution 4:

When a variable is assigned a value inside a function, that variable name is considered local. Unless it is explicitly declared as global with the line:

global x

In the first print of the function the variable x is not defined in the local scope. That-s why throws an error.

So you have to add the line global x at the beggining of the function body for the variable x be considered global despite it is assigned in the function.

Post a Comment for "How Scope Is Determined In Python"