Home > OS >  How scope is determined in Python
How scope is determined in Python

Time:10-17

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
    print(x)

Running the first function gives the following result.

>>> function_a()
5

While running the second function throws an error.

UnboundLocalError: local variable 'x' referenced before assignment

CodePudding user response:

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

To demonstrate this I created two scenarios.

Variable declared in the inner scope

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

Inferred Inner

No variables declared in 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 switch 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 global, and not the inner scope.

x = 5

def scope():
    global x
    print(x)
    x = 7
    print(x)

Scopes

By choosing which scope to work with, you are not only using the variables within that specific scope, but you are also modifying the variables. Therefore, you need to be extra careful 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 = 5

def outer():
    x = 7

    def inner():
        nonlocal x
        print(x)
        x = 3
        print(x)
    
    inner()

CodePudding user response:

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 = 5

def vs_code():
    print(x)

def vs_code1():
    print(x)
    y = 7
    print(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.

CodePudding user response:

python is special in variable scope

you can use dis module to see what happeded.

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

output

  2           0 LOAD_GLOBAL              0 (print)
              2 LOAD_FAST                0 (x)
              4 CALL_FUNCTION            1
              6 POP_TOP

  3           8 LOAD_GLOBAL              0 (print)
             10 LOAD_GLOBAL              1 (y)
             12 CALL_FUNCTION            1
             14 POP_TOP

  4          16 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

def vs_code1():
    global x
    print(x)
    x = 7
    print(x)

CodePudding user response:

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.

  • Related