为什么在python中修改局部变量是个坏主意?

为什么在python中修改局部变量是个坏主意?,python,locals,Python,Locals,关于这一答复。本地医生 文档提到字典不应该改变,不确定它的意思,但是locals()是否适用于数据不变的实验室报告,例如测量 来自 局部变量是一个返回 字典,在这里你设置了一个 在那本字典里。你可以 你认为这会改变价值吗 局部变量x到2,但它 不。事实上,当地人并不这么认为 返回本地名称空间,它将返回 一份。所以改变它对你没有任何影响 中变量的值 本地名称空间 文档说明的是,当您有一个本地x变量并执行locals()['x']=42时,x可能仍然指向旧对象 def foo(): x =

关于这一答复。本地医生

文档提到字典不应该改变,不确定它的意思,但是
locals()
是否适用于数据不变的实验室报告,例如测量

来自

局部变量是一个返回 字典,在这里你设置了一个 在那本字典里。你可以 你认为这会改变价值吗 局部变量x到2,但它 不。事实上,当地人并不这么认为 返回本地名称空间,它将返回 一份。所以改变它对你没有任何影响 中变量的值 本地名称空间


文档说明的是,当您有一个本地
x
变量并执行
locals()['x']=42
时,
x
可能仍然指向旧对象

def foo():
    x = 0xABCD
    locals()['x'] = 42
    print(x)

foo()

修改是一个坏主意,因为文档(您链接的文档)明确表示不要:

注意:本词典的内容不得修改;更改可能不会影响解释器使用的本地变量和自由变量的值

你不需要更多的理由了

如果您使用它的方式不修改任何变量,那么您会很好,但我会质疑设计,看看是否有更好的方式来做您想要的事情


在您链接的特定示例中,局部变量实际上是globals(),因为您在模块的全局范围内使用它。这个非常具体的用法现在可以使用了,尽管我希望它会像globals一样继续工作,但您也可以使用globals来代替


一个更干净的解决方案可能是,在不了解其他设计的情况下,对变量使用常规的ol字典;然后使用data[“x”]=value而不是globals()[“x”]=value。

在CPython解释器中,局部变量可以来自多个地方(这方面的细节并不重要,但它与如何存储闭包的变量有关)。
locals()
函数收集所有这些位置的名称和值,以便您方便地在一个位置访问所有这些名称和值,但由于它不知道给定变量的来源,因此无法将其放回原处。换句话说,这是个坏主意,因为它不起作用。

在某些情况下,对locals()的调用返回从多个源收集的值,而不是指向本地范围的指针

示例:在函数调用中,locals()返回函数的全局作用域和局部作用域的组合。在这种情况下,修改locals()输出不会对本地范围进行任何更改,因为它实际上使用的是孤岛。它似乎只有在其输出与globals()的输出相同的情况下才起作用


因此,换句话说,您要么想使用globals(),要么想找到不同的方法来实现相同的目标。

这是不准确的:
locals()
并不总是返回副本。但是,修改
locals()
实际上会产生影响的情况是一个实现细节,而不是语言定义的一部分,因此你不能依赖于这种行为。当有人问“为什么文档说这是个坏主意”时,回答是“因为文档这么说”这不是一个有用或有用的答案。@GlennMaynard:他没有说“为什么医生会说”,而是问“为什么这是个坏主意”。由于他无法更改行为和文档,文档中的警告足以证明他不能修改值,尤其是在有两种简单的解决方法(上述两种方法)的情况下。有没有理由不这样做?实际上,我正试图结合exec/eval做类似的事情,但这是不可能的。为什么Python 3.6不允许我更改前面的变量?@PiMathCLanguage,因为您几乎肯定不必这样做。动态更改本地名称空间几乎从来没有一个好的用例,因为允许这样做会阻止Python 3中的优化(本地名称空间不再是一个
dict
,而是一个用于更快查找的数组),然后,语言设计师决定,让你这么做还不够重要,在《什么是岛屿?》中描述了一个非常粗糙和丑陋的解决方法。我不知道我的意思。哈!我猜“岛”是指与周围环境隔绝的东西。因此,
locals()
字典保存副本而不是指向原始对象的指针,这就是为什么修改
locals()
不会修改原始对象的原因。