use*_*155 2 python global function local execfile
python文档声明"execfile()不能可靠地用于修改函数的本地." 在页面http://docs.python.org/2/library/functions.html#execfile上
任何人都可以提供此声明的任何进一步细节吗 文档相当少.该语句似乎与"如果省略两个字典,表达式在调用execfile()的环境中执行非常矛盾." 这也在文档中.在函数中使用excecfile时是否存在特殊情况,然后execfile的作用类似于函数,因为它创建了一个新的作用域级别?
如果我在一个函数中使用execfile
def testfun():
execfile('thefile.py',globals())
def testfun2():
print a
Run Code Online (Sandbox Code Playgroud)
并且有'thefile.py'中的命令创建的对象(例如对象'a'),我怎么知道它们是testfun还是全局对象的本地对象?那么,在函数testfun2中,'a'似乎是全局的?如果我从execfile语句中省略了globals(),那么任何人都可以更详细地解释为什么'thefile.py'中的命令创建的对象不能用于'testfun'?
在Python中,查找名称的方式在函数内部进行了高度优化.其中一个副作用是返回的映射locals()为您提供函数内部本地名称的副本,并且更改该映射实际上不会影响该函数:
def foo():
a = 'spam'
locals()['a'] = 'ham'
print(a) # prints 'spam'
Run Code Online (Sandbox Code Playgroud)
在内部,Python使用LOAD_FAST操作码通过索引查找a当前帧中的名称,而不是较慢的,它将查找本地名称(按名称),然后在映射中查找,如果在第一个中找不到.LOAD_NAMEglobals()
python编译器只能LOAD_FAST为编译时已知的本地名称发出操作码; 但如果你允许locals()直接影响函数的本地人,那么你就不能提前知道所有的本地名称.使用范围名称(自由变量)的嵌套函数使问题复杂化.
在Python 2中,您可以强制编译器关闭优化并LOAD_NAME始终使用exec函数中的语句:
def foo():
a = 'spam'
exec 'a == a' # a noop, but just the presence of `exec` is important
locals()['a'] = 'ham'
print(a) # prints 'ham'
Run Code Online (Sandbox Code Playgroud)
在Python 3中,exec已被替换,exec()并且解决方法已经消失.在Python 3中,所有功能都经过优化.
如果你没有遵循这一切,那也没关系,但这就是为什么文档略微掩盖了这一点.这完全归功于大多数Python用户不需要理解的CPython编译器和解释器的实现细节; 所有你需要知道的是locals(),通常使用改变函数中的本地名称是行不通的.