Python 函数 locals() 只是通过调用它来改变的

0 python function local-variables

请阅读这两个代码,我发现唯一不同的是是否打印 locals()。但其中之一是错误的。请帮助我,谢谢

import numpy as np

class Solution:
    def solve(self, f, a, b, n):
        x = np.linspace(a,b,n)
        # print(locals())
        loc = locals()
        fstr = '''
def fun(x):
    return %s
        ''' % f
        exec(fstr)
        # print(locals())
        fun  = loc['fun']
        y = fun(x)
        print(x,y,sep = '\n')

a = Solution()
a.solve('x+1',-5,5,5)
Run Code Online (Sandbox Code Playgroud)

在这段代码中,我没有打印 locals()

如果我只打印它并在 "fun = loc['fun']" 和 "y = fun(x)" 前面写上 '#',则 locals() 的输出中有一个名为 'fun' 的键

import numpy as np

class Solution:
    def solve(self, f, a, b, n):
        x = np.linspace(a,b,n)
        # print(locals())
        loc = locals()
        fstr = '''
def fun(x):
    return %s
        ''' % f
        exec(fstr)
        print(locals())
        fun  = loc['fun']
        y = fun(x)
        print(x,y,sep = '\n')

a = Solution()
a.solve('x+1',-5,5,5)
Run Code Online (Sandbox Code Playgroud)

但是在这段代码中,我在 locals() 的输出中找不到名为“fun”的键

Traceback (most recent call last):
  File "tmp.py", line 20, in <module>
    a.solve('x+1',-5,5,5)
  File "tmp.py", line 15, in solve
    fun  = loc['fun']
KeyError: 'fun'
Run Code Online (Sandbox Code Playgroud)

所有这些似乎都是“fun = loc['fun']”和“y = fun(x)”决定了locals()的输出

但我认为python是不可能的,后面的代码可以改变前面的代码

use*_*ica 5

是的,这发生在locals(). locals()令人困惑并且没有很好的记录。

locals()在同一堆栈帧中重复调用每次都会返回相同的 dict,并且每次调用都会使用局部(或闭包)变量的当前值locals() 更新该 dict。dict 作为其f_locals属性附加到堆栈帧,访问该属性也将更新 dict。

为了locals()安全使用而不会发生不可预测的值变化,您应该复制返回的字典:

current_locals = locals().copy()
Run Code Online (Sandbox Code Playgroud)

否则,即使在调试器中运行您的代码也可能改变其行为,因为调试器通常会访问f_locals检查局部变量。


此外,尝试exec在本地范围内分配任何变量的代码是官方不支持的,并且行为很奇怪,并被def视为分配。exec无论如何你不应该使用它。