1

我有一个局部变量x = "local",不幸的是它与全局变量和非局部变量共享它的名称。在不更改任何名称的情况下,我可以访问所有三个值吗?因为x = "global"globals(),但是非局部变量呢?

说明问题的最小示例:

x = "global"
def f(x="nonlocal"):
    def g():
        x = "local"
        print(x)  # same as locals()["x"]
        print(globals()["x"])
        # here I want to print the non-local x
    return g

f()()
4

3 回答 3

2

我不知道您必须使用相同的名称。
无论如何,您可以将外部函数的局部变量捕获为非局部变量。

x = "global"


def f(x="nonlocal"):
    nonlocals = locals()

    def g():
        x = "local"
        print(x)
        print(nonlocals['x'])
        print(globals()["x"])

    return g


f()()

输出:

local
nonlocal
global
于 2020-03-23T13:20:15.693 回答
1

尽管您无法使用完全按照给定编写的代码来执行此操作,但您可以使用检查来获取非局部变量。注意调用和返回的变化。如果调用者是外部作用域而不是全局作用域,则前一帧将为f.

import inspect

x = "global"
def f(x="nonlocal"):
    def g():
        x = "local"
        print(x)
        print(globals()["x"])
        print(inspect.currentframe().f_back.f_locals["x"])

    return g()


f()

输出

局部
全局
非局部

这在这种特定情况下可能无济于事,这实际上取决于您对f. 如果您无法控制它,您也可以使用 monkey-patch f。很大程度上取决于上下文。

于 2020-03-29T18:10:56.830 回答
0

编辑:我没有注意到这个问题没有使用nonlocal. 将其留在这里以防其他人发现它有用。


我质疑这背后的基本原理,但在 Python 3 中,您可以使用nonlocal关键字访问以前的范围,在重新声明之前存储它,然后再获取它。

x = "global"
def f(x="nonlocal"):
    def g():
        nonlocal x
        y = x
        x = "local"
        print(x)  # same as locals()["x"]
        print(globals()["x"])
        print(y)
    return g


f()()

输出

local
global
nonlocal
于 2020-03-23T13:27:52.350 回答