I want to use Python files to configure a program. The files will be read via exec
. Part of the configuration are class definitions:
config.py
import collections as col # module alias does not matter
a = col.defaultdict() # works as expected
class Foo:
b = col.defaultdict() # causes NameError: name 'col' is not defined
main.py
CONFIG = {}
with open('config.py') as f:
exec(f.read(), None, CONFIG)
Now, when running main.py I'll have the problem that outside of the class definition the imported module is known but inside it is not. Why and is there a workaround?
According to exec's documentation,
If exec gets two separate objects as globals and locals, the code will be executed as if it were embedded in a class definition.
So your config.py code is equivalent to
class SomeClass:
import collections as col
a = col.defaultdict()
class Foo:
b = col.defaultdict()
This is a problem because, according to Resolution of Names,
The scope of names defined in a class block is limited to the class block[.]
col
is defined in the class block of the implicit SomeClass
. This variable's scope is limited to that class block only; even blocks inside that block, such as class Foo:
, can't access it.
One possible solution is to pass the same object for globals
and locals
so that your code is not executed as if it were embedded in a class definition.
exec(f.read(), CONFIG, CONFIG)