繁体   English   中英

python中'nonlocal'关键字的用法

[英]Usage of 'nonlocal' keyword in python

下面的程序询问带有UnboundLocalError: local variable 'balance' referenced before assignment nonlocal关键字UnboundLocalError: local variable 'balance' referenced before assignment

>>> def make_withdraw(balance):
    """Return a withdraw function with a starting balance."""
    def withdraw(amount):
        if amount > balance:
            return 'Insufficient funds'
        balance = balance - amount
        return balance
    return withdraw

>>> withdraw = make_withdraw(101)
>>> withdraw(25)

但是,当内部函数shift在赋值之前将lst引用为temp = lst[0]时,以下程序不会给出此类错误。

def shift_left(lst, n):
    """Shifts the lst over by n indices

    >>> lst = [1, 2, 3, 4, 5]
    >>> shift_left(lst, 2)
    >>> lst
    [3, 4, 5, 1, 2]
    """
    assert (n > 0), "n should be non-negative integer"
    def shift(ntimes):
        if ntimes == 0:
            return
        else:
            temp = lst[0]
            for index in range(len(lst) - 1):
                lst[index] = lst[index + 1]         
            lst[index + 1] = temp
            return shift(ntimes-1)
    return shift(n)

我如何理解/比较这两种情况?

您永远不会分配给lst ,而只会分配给lst[index] 这两个概念并不完全相同。

该行:

lst = some_other_value

将重新绑定名称lst指向另一个对象。 该行:

lst[index] = some_other_value

通过将序列中的特定索引绑定到其他对象来更改名称lst引用的对象。 名称lst本身从未更改,因此在此名称所属的范围方面没有任何歧义。

在Python作用域中,只有对名称本身的绑定操作才算在内。 绑定操作不仅是(直接)赋值,还包括函数参数,函数和类定义, import语句和目标, except .. aswith .. as和目标in for ... in循环外。 如果在给定范围内绑定了名称,则将其视为本地名称 ,在所有其他情况下,Python会在父范围内查找名称,最外层的范围为global

在这种情况下,对订阅的分配(使用[...] )不是绑定操作。

请参阅Python执行模型文档的命名和绑定部分 ,以及作用域规则简短说明? 帖子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM