Python在函数内部使用vars()[mystring]基于另一个变量创建变量时会失败。
问题的原因是在函数内部使用vars()[mystring]
创建变量时会失败。这是因为在函数内部,局部变量是通过LOAD_FAST
操作码来访问的,除非在函数中有一个exec
语句。为了支持这个语句,它可以在编译时创建不被知道的新变量,Python被强制在函数内部按名称访问局部变量,所以写入locals()
可以工作。这个exec
可以在不执行的代码路径之外。
解决方法是使用locals()[varname] = 42
来创建变量。然后,通过locals()[xxx]
来访问变量。如果你不知道变量的名称,你可以使用自己的字典而不是污染locals()
并有可能覆盖函数实际需要的变量。这样做虽然可行,但并不推荐。
需要注意的是,这个方法只适用于Python 2.x版本。Python 3已经放弃了这种方法,其他实现(如Jython、IronPython等)可能也不支持这种方法。
在上面的内容中,作者提到了一种使用vars()[mystring]
的方法来创建变量的尝试失败了。这个问题出现在一个函数内部。解决这个问题的方法是使用exec
函数来执行一段已经编译过的代码块。
具体来说,作者首先创建了一个包含一系列变量赋值语句的字符串code_text
,然后使用compile()
函数将这段字符串编译为可执行的代码块code_chunk
。最后,使用exec code_chunk
来执行这段代码块。
作者提到了为什么要这样做,如果可以使用字典来实现同样的功能,为什么还要用这种方式。他解释说,虽然这种方法并不是最佳实践,但在某些情况下可能会有用。这个问题可能更多是理论上的,不太适用于实际情况。
总结起来,这个问题的原因是在一个函数内部使用vars()[mystring]
来创建变量失败了。解决方法是使用exec
函数来执行已经编译过的代码块。
Python中,无法直接修改`locals()`并期望它正常工作。在函数内部修改`locals()`的行为是不确定的。在函数外部,当`locals()`和`globals()`相同时,它是可以工作的。解决方法是使用字典,或者在对象上设置属性。在Python中,对于那些不是函数的命名空间(如模块、类定义、实例),通常通过字典查找来访问变量。函数的局部变量可以进行优化,因为编译器通常在调用`locals()`之前就已经知道所有的变量名,所以在调用`locals()`之前并不会创建一个字典。在Python的C实现中,调用`locals()`(在函数内部)会创建一个普通的字典,其初始值为当前局部变量的值。在每个函数内部,对`locals()`的任意次调用都将返回相同的字典,但是每次调用`locals()`都会使用当前局部变量的值来更新它。这会给人一种赋值给字典元素被忽略的印象,因此对从`locals()`返回的字典中的现有键的修改仅在同一作用域内的下一次调用`locals()`之前有效。在IronPython中,情况有些不同。在内部调用`locals()`的任何函数都使用一个字典作为其局部变量,因此对局部变量的赋值会更改字典,并且对字典的赋值会更改变量。但是,这只适用于在IronPython中显式调用名为`locals()`的函数。如果在IronPython中将不同的名称绑定到`locals`函数,那么调用它将为绑定该名称的作用域返回局部变量,并且没有办法通过它访问函数局部变量。在Python的C实现中,`locals()`的返回值是一个标准的字典。两个小的修正:1. 在CPython 2.x和3.x中,`locals()`的返回值是一个标准字典,可以像通常一样进行更改(但更改不会传播回局部作用域)。2. 访问类和实例命名空间并不总是涉及字典查找。有几个例外情况,包括定义了`__slots__`的类的实例。