execfile()无法可靠地用于修改函数的本地变量 [英] execfile() cannot be used reliably to modify a function’s locals

查看:93
本文介绍了execfile()无法可靠地用于修改函数的本地变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

python文档指出不能可靠地使用execfile()修改函数的本地变量."在 http://docs.python.org/2/library/functions页面上. html#execfile

The python documentation states "execfile() cannot be used reliably to modify a function’s locals." on the page http://docs.python.org/2/library/functions.html#execfile

任何人都可以提供此声明的更多详细信息吗?该文档相当少.该语句似乎与如果省略两个字典,则在调用execfile()的环境中执行该表达式"的矛盾.在文档中也有.如果在函数中使用excecfile,然后execfile的行为类似于函数,是否会创建新的作用域级别,这是否是一种特殊情况?

Can anyone provide any further details on this statement? The documentation is fairly minimal. The statement seems very contradictory to "If both dictionaries are omitted, the expression is executed in the environment where execfile() is called." which is also in the documentation. Is there a special case when excecfile is used within a function then execfile is then acting similar to a function in that it creates a new scoping level?

如果我在

def testfun():
    execfile('thefile.py',globals())
    def testfun2():
        print a

"thefile.py"中有一些由命令创建的对象(例如对象"a"),我怎么知道它们将成为testfun的局部对象还是全局对象?那么,在函数testfun2中,"a"似乎是全局的吗?如果我从execfile语句中省略了globals(),那么谁能给出更详细的解释,为什么'thefile.py'中的命令创建的对象不能用于'testfun'?

and there are objects created by the commands in 'thefile.py' (such as the object 'a'), how do I know if they are going to be local objects to testfun or global objects? So, in the function testfun2, 'a' will appear to be a global? If I omit globals() from the execfile statement, can anyone give a more detailed explanation why objects created by commands in 'thefile.py' are not available to 'testfun'?

推荐答案

在Python中,名称的查找方式在函数内部得到了高度优化.副作用之一是locals()返回的映射为您提供了函数内部本地名称的副本,并且更改该映射实际上不会影响该函数:

In Python, the way names are looked up is highly optimized inside functions. One of the side effects is that the mapping returned by locals() gives you a copy of the local names inside a function, and altering that mapping does not actually influence the function:

def foo():
    a = 'spam'
    locals()['a'] = 'ham'
    print(a)              # prints 'spam'

在内部,Python使用LOAD_FAST操作码通过索引在当前帧中查找a名称,而不是使用较慢的LOAD_NAME来查找本地名称( (按名称)),然后在globals()映射中找到(如果没有找到).

Internally, Python uses the LOAD_FAST opcode to look up the a name in the current frame by index, instead of the slower LOAD_NAME, which would look for a local name (by name), then in the globals() mapping if not found in the first.

python编译器只能为编译时已知的本地名称发出LOAD_FAST操作码;但是,如果允许locals()直接影响函数的本地名称,那么您将无法提前知道所有本地名称.使用作用域名称(自由变量)的嵌套函数会使事情变得更加复杂.

The python compiler can only emit LOAD_FAST opcodes for local names that are known at compile time; but if you allow the locals() to directly influence a functions' locals then you cannot know all the local names ahead of time. Nested functions using scoped names (free variables) complicates matters some more.

在Python 2中,您可以通过在函数中使用exec语句来强制编译器关闭优化并始终使用LOAD_NAME:

In Python 2, you can force the compiler to switch off the optimizations and use LOAD_NAME always by using an exec statement in the function:

def foo():
    a = 'spam'
    exec 'a == a'         # a noop, but just the presence of `exec` is important
    locals()['a'] = 'ham'
    print(a)              # prints 'ham'

在Python 3中,exec已由exec()替换,并且变通办法消失了.在Python 3中,所有函数均已优化.

In Python 3, exec has been replaced by exec() and the work-around is gone. In Python 3 all functions are optimized.

如果您不遵循所有这些说明,那也很好,但这就是为什么文档对此有所掩饰的原因.这完全是由于大多数Python用户不需要了解CPython编译器和解释器的实现细节.所有您需要知道的是,通常无法使用locals()更改函数中的本地名称.

And if you didn't follow all this, that's fine too, but that is why the documentation glosses over this a little. It is all due to an implementation detail of the CPython compiler and interpreter that most Python users do not need to understand; all you need to know that using locals() to change local names in a function does not work, usually.

这篇关于execfile()无法可靠地用于修改函数的本地变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆