TL; DR:我想要一个在包含范围内查找的locals()。
大家好。
我正在向一些化学家朋友讲授关于Python编程的课程,我想确保我真正了解范围。
考虑:
def a():
x = 1
def b():
print(locals())
print(globals())
b()
Locals打印一个空的环境,globals打印通常的全局变量。如何访问存储x的环境?显然,口译员知道它,因为我可以参考它。
相关:什么时候发生范围?仅当包含x = 3时,a = x + 2上的以下nameErrors:
def a():
x = 1
def b():
a = x+2
x = 3
b()
如果您注释掉x = 3,则代码可以正常工作。这是否意味着python在解释代码之前会对代码进行词法范围传递?
答案 0 :(得分:0)
python3 -c "help(locals)"
谈到locals
函数:
locals()
Return a dictionary containing the current scope's local variables.
这意味着在locals()
中调用b()
只会向您显示b()
局部变量。这并不意味着b()
在其范围之外看不到变量,而是locals()
仅返回b()
本地变量的信息。
您可能想要使b()
显示有关调用函数变量的信息。为此,请使用以下代码(其中显示了b()
的局部变量):
def a():
x = 1
def b():
print(locals())
b()
并将其替换为该代码(使用inspect
模块来获取调用帧的本地信息)
def a():
x = 1
def b():
import inspect
print(inspect.currentframe().f_back.f_locals)
b()
关于您的其他问题:
def a():
x = 1
def b():
a = x+2
x = 3
b()
您得到的错误是因为Python 3允许您设置/分配全局变量和外部作用域局部变量,前提是您使用global
和nonlocal
关键字对其进行了声明。 (我不会在这里解释它们;我只是说您自己查找它们不会有任何问题。)
如果删除x = 3
行(保留a = x+2
行),则代码将运行,因为正在使用x
的值,但未设置。相反,如果删除a = x+2
行(保留x = 3
行),则代码将运行,因为它将在x
范围内创建一个新的b()
。
如果同时保留这两行,Python将不知道x
是否应该引用当前范围之外的x
(正如a = x+2
所暗示的那样)或是否应该引用x
范围内的b()
(如x = 3
所建议的那样。)
如果您希望x
在b()
本地,那么您不应该在那儿拥有a = x+2
行,至少在将x
设置为{{ 1}}。但是,如果您希望x = 3
是x
的{{1}},则应该将a()
声明为x
至x
,如下所示:< / p>
nonlocal
如果您感到困惑,请记住,Python将允许您使用全局变量和在当前作用域之外创建的变量,但前提是您不分配他们。 (读取全局变量通常是可以接受的,但是设置它们并不受欢迎。)
如果要设置全局变量或非局部变量,则必须使用b()
(对于全局变量)或def a():
x = 1
def b():
nonlocal x # use a()'s x
a = x+2
x = 3
b()
(对于非局部变量)声明这些变量,如上面的代码所示。
我希望这会有所帮助。