0

When I run

def classMaker(x):
    class y(object):
        x=x
    return y

Y = classMaker("value")

I get the following error

Traceback (most recent call last):
  File "bug.py", line 6, in <module>
    classMaker("value")
  File "bug.py", line 2, in classMaker
    class y(object):
  File "bug.py", line 3, in y
    x=x
NameError: name 'x' is not defined

but x="value". What's going on?

PyRulez
  • 10,513
  • 10
  • 42
  • 87
  • This is an exact duplicate, good discussion in the answer above. – user3483203 Mar 11 '18 at 06:21
  • That duplicate gets a frustrating number of nuances wrong; for example, edit 5 in the question thinks that class scopes can't access variables from enclosing function scopes at all. – user2357112 Mar 11 '18 at 06:31

2 Answers2

1

Name lookup at class scope is weird and not really consistent with its documentation.

Normally, unlike with a function scope, name lookup in a class scope happens the same regardless of whether the scope has assignments to the name; locals first, then globals, then builtins. However, nonlocal lookup in a class scope is affected by assignments in that class scope.

If you do something like

def classMaker(x):
    class y(object):
        z=x  # not x=x
    return y

Python sees that the name x matches a nonlocal variable, and it uses the LOAD_DEREF opcode to access the closure cell for that variable. However, the assignment to x in your actual code:

def classMaker(x):
    class y(object):
        x=x
    return y

causes Python to use LOAD_NAME, the usual opcode for class-scope name lookup, which doesn't see closure variables.

user2357112
  • 260,549
  • 28
  • 431
  • 505
-1

It's not equal. You undeclaring it by assigment and trying to assign to new, undefined variable. Use another name.

def classMaker(z):
    class y(object):
        x=z
    return y

Y = classMaker("value")
Amaro Vita
  • 437
  • 3
  • 9