求救:在线程中执行execfile的问题

求救:在线程中执行execfile的问题

在线程中运行execfile会出现NameError的异常, 比如“NameError: global name 'time' is not defined”,但time确实已经被import了

代码:
调用者:
from threading import Thread
class T(Thread):
    def run(self):
        execfile('mytest.py', {}, {})

if __name__ == '__main__':
    T().run()

被调用者: mytest.py
import time
def test():
    print time.time()

test()

运行的异常是:
Traceback (most recent call last):
  File "testthread.py", line 10, in <module>
    T().run()
  File "testthread.py", line 6, in run
    execfile('mytest.py', {}, {})
  File "mytest.py", line 8, in <module>
    test()
  File "mytest.py", line 4, in test
    print time.time()
NameError: global name 'time' is not defined
上面的代码还不是在线程中执行的,
把T().run() 改成 T().start() 问题依旧。
execfile中的globals不能使用默认值,而locals要使用默认值就可以了。
即把
execfile('mytest.py', {}, {})

改成
execfile('mytest.py', {})
引自:http://tenyears.cn/index.php/2007/12/18/python-execfile.html

不懂! 谁能解释下?

execfile的问题
最近在使用Python的execfile调用另外一个Python脚本时,遇到了莫名其妙的问题。在execfile中使用默认参数时,就会报类似“NameError: global name 'time' is not defined”的错误。

被调用者:
import time
def test():
print time.localtime()

test()
调用者:
def run():
execfile('mytest.py')
run()

就会出现“NameError: global name 'time' is not defined”的异常。但把 execfile('mytest.py') 改成execfile('mytest.py', {})就是正确的。原因估计是在方法中调用execfile时的默认globals与直接调时不一样,具体原因需要看看Python的源代码了。   


在这个程序如果用了execfile('mytest.py'), globals是什么?locals是什么?把globals设置为{}什么意思呢?

引自:http://coding.derkeiler.com/Archive/Python/comp.lang.python/2007-08/msg00378.html

还是看不懂啊!

Fernando Perez wrote:

I'm finding the following behavior truly puzzling, but before I post a bug
report on the site, I'd rather be corrected if I'm just missing somethin
obvious.

Consider the following trivial script:

[Copy to clipboard] [ - ]
CODE:
from math import sin, pi
wav = lambda k,x: sin(2*pi*k*x)
print wav(1,0.25)

The above runs just fine from a prompt, or even interactively via
execfile(). Now, consider calling it by using this instead:

[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/env python
def runscript(fname):
"""Run a file by calling execfile()."""
        execfile(fname)
runscript('execfilebugscript.py')

If I run the above, calling the first script 'execfilebugscript.py' and
the second 'execfilebug.py', I get this:

[Copy to clipboard] [ - ]
CODE:
NameError: global name 'sin' is not defined

I'm really, really puzzled by this. From reading the execfile() docs, I
had the hunch to change the call to:

[Copy to clipboard] [ - ]
CODE:
execfile(fname,{})

and now the problem disappears, so I can keep on working.


回答:
If you execfile() a script names not known in the context of a function are
looked up in the global namespace, but assignments set names in the local
namespace.

Consider execfile(filename) for a file

[Copy to clipboard] [ - ]
CODE:
x = 42
def f():
       print x
f()

x and f are put into the local namespace, but x is not local to the function
f and therefore looked up in f's globals.

Now if you call execfile() in the global namespace of the client script the
global and local namespace are identical

[Copy to clipboard] [ - ]
CODE:
globals() is locals()

True

so x although put into the local namespace will still be found when looked
up in the global namespace. That is the same situation as in your
workaround execfile(filename, {}).

This however is not the case if you call execfile() inside a function. Here
global and local namespace differ.

In your example, when you put another execfile() into the global namespace
of the client script the sin() imported there is the only one that your
wav() function sees. You can verify that by putting

[Copy to clipboard] [ - ]
CODE:
def sin(phi): return "I'm not math.sin()"

instead of

[Copy to clipboard] [ - ]
CODE:
if 1: ....

into execfilebug.py.

Can the current behaviour of execfile() be changed into a more intuitive
one? Not with only two namespaces. You'd probably need something similar to
closures, and I don't think the necessary work would be worth the effort.
Peter


Peter最后这几句什么意思?

官方文档:

execfile( filename[, globals[, locals]])

This function is similar to the exec statement, but parses a file instead of a string. It is different from the import statement in that it does not use the module administration -- it reads the file unconditionally and does not create a new module.2.2
The arguments are a file name and two optional dictionaries. The file is parsed and evaluated as a sequence of Python statements (similarly to a module) using the globals and locals dictionaries as global and local namespace. If provided, locals can be any mapping object. Changed in version 2.4: formerly locals was required to be a dictionary. If the locals dictionary is omitted it defaults to the globals dictionary. If both dictionaries are omitted, the expression is executed in the environment where execfile() is called. The return value is None.

Warning: The default locals act as described for function locals() below: modifications to the default locals dictionary should not be attempted. Pass an explicit locals dictionary if you need to see effects of the code on locals after function execfile() returns. execfile() cannot be used reliably to modify a function's locals.

到底啥球意思??