如何/啥是嵌套函数中声明为非本地设置的变量的值?

Posted

技术标签:

【中文标题】如何/啥是嵌套函数中声明为非本地设置的变量的值?【英文标题】:How/what is the value of a variable in a nested function declared nonlocal set to?如何/什么是嵌套函数中声明为非本地设置的变量的值? 【发布时间】:2018-09-18 23:11:31 【问题描述】:
def make_test_dice(*outcomes):
    """Return a die that cycles deterministically through OUTCOMES.

    >>> dice = make_test_dice(1, 2, 3)
    >>> dice()
    1
    >>> dice()
    2
    >>> dice()
    3
    >>> dice()
    1
    """
    assert len(outcomes) > 0, 'You must supply outcomes to make_test_dice'
    for o in outcomes:
        assert type(o) == int and o >= 1, 'Outcome is not a positive integer'
    index = len(outcomes) - 1
    print("Index1: ", index)
    def dice():
        nonlocal index 
        index = (index + 1) % len(outcomes)
        print("Index2: ", index)
        return outcomes[index]
    return dice

def main(): 
    foursided = make_test_dice(4,1,2)
    foursided()
    foursided()

if __name__ == "__main__": main()

所以我意识到,在调用 make_test_dice 之后,当调用foursided 时,它会跳过 index1 var 的打印并转到 dice 函数,因为这是一个闭包。我知道非局部变量是指封闭范围内的变量,因此更改嵌套函数中的 var 会在外部更改它,但我不明白 index 变量如何存储在嵌套函数中,因为它在 dice() 中设置值时需要一个值索引。鉴于我的打印语句,我相信它可能是 index 的先前值,但我认为 index 在我们退出 make_test_dice 函数的本地框架后会消失。

【问题讨论】:

请不要重复问题***.com/questions/49729112/…,正如我所说,请阅读 nonlocal 的作用 ***.com/questions/1261875/python-nonlocal-statement 我确实读过 nonlocal 做了什么,但它没有回答索引变量是如何在函数调用之间存储的。我知道 nonlocal 使外部函数作用域中的变量在内部作用域中可变,而不创建同名的新 var,但这并不能回答我的主要问题。 你似乎不明白nonlocal,因为这解释了index 是如何更新的,有点像global。试试这个,x = 0 然后def f(): global x: x += 1,然后多次调用f()print(x) 【参考方案1】:

我意识到在调用 make_test_dice 之后,当调用foursided时,它会跳过 index1 var 的打印并转到 dice 函数,

什么都没有被跳过 - foursided 是“骰子功能”。或者,更准确地说,它是在 foursided = make_test_dice(4,1,2) 调用期间创建的函数对象 - 每次调用 make_test_dice() 都会创建一个新的“骰子”函数。

因为这是一个闭包

看起来您并不真正了解闭包的实际含义。

我知道非局部变量是指封闭范围内的变量,因此更改嵌套函数中的 var 会在外部更改它,但我不明白 index 的变量如何存储在嵌套函数中

嗯,这正是闭包的全部意义所在:它们确实捕获了定义它们的环境。在 Python 中,函数是对象(内置 function 类的实例),它们只使用实例属性:

def show_closure(func):
    print(func.__closure__)
    for cell in func.__closure__:
        print(cell.cell_contents)


foursided = make_test_dice(4,1,2)
for i in range(4):
    show_closure(foursided)
    foursided()

【讨论】:

以上是关于如何/啥是嵌套函数中声明为非本地设置的变量的值?的主要内容,如果未能解决你的问题,请参考以下文章

JAVA语言中,啥是变量,如何定义一个变量?啥是常量?

函数与闭包

在C语言中啥是全局变量?用一个小程序段说明下,谢谢,

Python内嵌函数与Lambda表达式

请问啥是成员函数的定义?

小甲鱼Python第十九讲课后习题