1

Consider the following code:

class A:
    ID = 5
    VALUES = ((4, "four"), (5, "five"))
    MAP = {
        t[0]: t[1] for t in VALUES if t[0] != ID
    }

This is surprising (to me), because the VALUES symbol is found correctly, but the code gives the error "NameError: global name 'ID' is not defined".

Having just t[0]: t[1] for t in VALUES works. Why?

Petter
  • 37,121
  • 7
  • 47
  • 62

1 Answers1

3

There is an excellent and very detailed answer on the subject in the question pointed by @t.m.adam.

The short answer is:

Names in class scope are not accessible. Names are resolved in the innermost enclosing function scope. If a class definition occurs in a chain of nested scopes, the resolution process skips class definitions.

As for the solution, I believe the easiest way to achieve the desired result is to create the variable inside the __init__ function as follow:

class A:
    ID = 5
    VALUES = ((4, "four"), (5, "five"))

    def __init__(self):
        self.MAP = {
            t[0]: t[1] for t in self.VALUES if t[0] != self.ID
        }

If you print the result of self.MAP, you will get the following:

>>> my_instance = A()
>>> print(my_instance.MAP)
{4: 'four'}
Sébastien Lavoie
  • 877
  • 1
  • 11
  • 18