I am trying to load information into a user defined function for further processing. Since the input files must be generated by non-programmers I have chosen the following format:
#contents of vessel_data.txt
hull_length = 100000.
hull_width = 50000.
etc.
My function then loads the input file via execfile()
. I then want to group data into an array and pass that as the output of the function. Roughly like so:
file_path = ..\vessel_name.txt
def my_input_func(file_path):
execfile(file_path)
data = np.array([[hull_length],
[hull_width ],
[etc. ]])
return(data)
I know that loading data via exec()
and execfile()
are frowned upon, but bear in mind that the input are generated by non-programmers. Anyways, I get the following error:
NameError: global name 'hull_length' is not defined
After adding these lines, I can confirm that my variables are loaded into the local
name space as expected:
print 'Locals: ' + str([x for x in locals() if x[0] == 'h'])
print 'Globals: ' + str([x for x in globals() if x[0] == 'h'])
What puzzles me is why my function looks to the global
name space when I try to define my variables. I were under the impression that unless specifically stated, everything inside a function dealt with the name space local to the function. I can make it work by modifying my execfile()
command to:
execfile(file_path, globals())
but I am not interested in loading everything into the global name space.
So, how do I make this work without loading everything into the global
name space?
Kind regards, Rasmus
======== Edit =======
This is how I made it work based on Quentin's answer:
file_path = ..\vessel_name.txt
def my_input_func(file_path):
vessel_vars = {}
execfile(file_path, vessel_vars)
data = np.array([[vessel_vars['hull_length']],
[vessel_vars['hull_width'] ],
[vessel_vars['etc.'] ]])
return(data)
Cheers Quentin!
The docs for execfile() warn about wanting to modify a function local variables: it's not possible!
It's not about execfile() but about locals():
You will also get
NameError: global name 'a' is not defined
. This is possibly for optimization purposes. The solution here is to use a dictionary:Note: I 'm assuming that you're using Python 2 but it would be the same in Python 3, except that execfile() is now exec() and you need to open the file yourself.