Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execution of execfile() in a method with Python

I have a config.py script that has PREAMBLE information. I can use execfile() function to read the contents of the configuration file.

execfile("config.py")
print PREAMBLE
>>> "ABC"

However, when execfile() is called in a method, I have an error.

def a():
    execfile("config.py")
    print PREAMBLE

a()
>>> NameError: "global name 'PREAMBLE' is not defined"

What's wrong and how to solve this issue?

like image 949
prosseek Avatar asked Mar 11 '26 05:03

prosseek


2 Answers

You need to pass the global dictionary to execfile to achieve the same result:

def a():
    execfile("config.py",globals())
    print PREAMBLE

a()
>>> "some string"

If you don't want to pollute your global namespace, you can pass a local dictionary and use that:

def a():
    config = dict()
    execfile('/tmp/file',config)
    print config['PREAMBLE']

a()
>>> "some string"

For reference, in both cases above, /tmp/file contained PREAMBLE = "some string".

like image 52
isedev Avatar answered Mar 13 '26 19:03

isedev


The issue here is the namespaces in which the code runs when execfile() is called. If you study the documentation you will see that execfile() can take two namespace arguments to represent the global and the local namespaces for execution of the code.

At module level (i.e. when the execfile() call does not come from inside a function) then the module global namespace is used for both those namespaces. From inside a function the module globals are used as the global namespace and the local namespace is the function call namespace (which typically disappears when the call returns).

Consequently, since assignments preferentially bind names in the local namespace, executing the file sets up PREAMBLE inside the function call namespace, and so it can't be found at module level.

If your config files really are Python, wouldn't it be possible just to import them, or is there some organizational reason why that won't work? That way you could just import config and then refer to config.PREAMBLE in your code.

like image 37
holdenweb Avatar answered Mar 13 '26 18:03

holdenweb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!