3

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!

4

1 回答 1

4

execfile()的文档警告要修改函数局部变量:这是不可能的!

默认 locals 的行为如下面函数 locals() 所述:不应尝试修改默认 locals 字典。如果您需要在函数 execfile() 返回后查看代码对局部变量的影响,请传递一个显式局部变量字典。 execfile() 不能可靠地用于修改函数的局部变量。

这不是关于 execfile() 而是关于 locals():

def f():
   locals()['a'] = 3
   print(a)

你也会得到NameError: global name 'a' is not defined. 这可能是出于优化目的。这里的解决方案是使用字典:

file_path = os.path.join('..', 'vessel_name.txt')

def my_input_func(file_path):
    vessel = {}
    execfile(file_path, vessel)

    data = np.array([[vessel['hull_length']],
                     [vessel['hull_width'],
                     [vessel['etc.']])

    return(data)

注意:我假设您使用的是 Python 2,但它在 Python 3 中是相同的,除了 execfile() 现在是 exec() 并且您需要自己打开文件。

于 2013-09-05T08:40:36.003 回答