Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does assigning to a class attribute with the same name as a local variable raise a NameError?

Consider this class definition:

def func():
    x = 5

    class Foo:
        x = x

func()

I expected this to create a class with an attribute x set to 5 - but instead, it throws a NameError:

Traceback (most recent call last):
  File "untitled.py", line 7, in <module>
    func()
  File "untitled.py", line 4, in func
    class Foo:
  File "untitled.py", line 5, in Foo
    x = x
NameError: name 'x' is not defined

However, that error is only raised inside of a function, and only if x is a local variable. All of these snippets work just fine:

x = 5

class Foo:
    x = x
x = 5

def func():
    class Foo:
        x = x

func()
class Bar:
    x = 5

    class Foo:
        x = x
def func():
    x = 5

    class Foo:
        y = x

func()

What's causing this strange behavior?

like image 572
Aran-Fey Avatar asked Nov 08 '22 03:11

Aran-Fey


1 Answers

Because the Python compiler looks at all the l-values in a code block when determining which variables are local. Since in your problematic code, x is used as an l-value in the class block, it is regarded as a variable local to the class block, and as such, it is considered to be referenced before it is assigned a value, and hence the exception.

like image 117
blhsing Avatar answered Nov 14 '22 21:11

blhsing