Let's say I'm writing a class that does something that takes a lot of time.
class Example:
def expensive(self, arg):
return arg + 1
Since it takes a lot of time, there are few possible arguments and every result will be used many times, I decide to precompute the results when the application is started:
class Example:
def expensive(arg):
return arg + 1
EXPENSIVE = {
0: expensive(0),
1: expensive(1),
2: expensive(2),
# ...
}
del expensive
Note that this does work. Obviously, this is very repetetive, so I decide to use dictionary comprehension:
class Example:
def expensive(arg):
return arg + 1
EXPENSIVE = {x: expensive(x) for x in range(3)}
del expensive
Unfortunately, Python rejects this with the following error:
Traceback (most recent call last):
File ".code.tio", line 1, in <module>
class Example:
File ".code.tio", line 5, in Example
EXPENSIVE = {x: expensive(x) for x in range(3)}
File ".code.tio", line 5, in <dictcomp>
EXPENSIVE = {x: expensive(x) for x in range(3)}
NameError: name 'expensive' is not defined
To be honest, this really surprised me. Python's scoping rules were really intuitive to me so far. Why does this happen, and how can I work around it?