关于 In-functions Variables Besides locals() Dictionary 的信息

Information about In-functions Variables Besides locals() Dictionary

正如预期的那样,此代码引发了 UnboundLocalError。

x = 3

def f():
    print("locals: " + str(locals()))
    if x==3:
        print("x is 3!")
    x = 1

f()

然而,从输出中我们可以看出,locals()一开始是一个空字典:

locals: {}
Traceback (most recent call last):
  File "C:/Users/user/PycharmProjects/try/scatch.py", line 10, in <module>
    f()
  File "C:/Users/user/PycharmProjects/try/scatch.py", line 6, in f
    if x==3:
UnboundLocalError: local variable 'x' referenced before assignment

根据我收集到的信息,locals 字典包含 Python 知道的有关函数内变量的所有信息。显然,事实并非如此:除了locals()之外,函数内部必须有一些关于变量的信息。

我的问题是 - 这些信息到底是什么?我们可以在函数的开头访问其中的变量列表吗?

您在 CPython 中寻找的答案是 f.__code__.co_varnames 记录在 inspect 模块中。

>>> def f():
...     print(f.__code__.co_varnames)
...     x = 1
...     y = 2
>>> f()
('x', 'y')

同时 f.__code__.co_varnames(正如所指出的 ) works, here's way to find local assignments with AST:

import inspect,ast

x = 3

def find_ass_in_func(func):
    f_src = inspect.getsource(f)
    f_ast = ast.parse(f_src)
    return find_ass_in_src(f_ast.body)
def find_ass_in_src(bodies):
    ass = set()
    for b in bodies:
        if isinstance(b, ast.Assign):
            ass |= set(t.id for t in b.targets)
        if(hasattr(b, "body")):
            ass |= find_ass_in_src(b.body)
    return ass

def f():
    print("locals: " + str(locals()))
    print("local variables:", find_ass_in_func(f))
    if x==3:
        print("x is 3!")
        x = 5
        y = 6 # just for demonstration purpose
    x = 1

f()

输出:

locals: {}
local variables: {'x', 'y'}
Traceback (most recent call last):
  File "test.py", line 27, in <module>
    f()
  File "test.py", line 21, in f
    if x==3:
UnboundLocalError: local variable 'x' referenced before assignment