简体   繁体   English

python中'nonlocal'关键字的用法

[英]Usage of 'nonlocal' keyword in python

Below program asks for nonlocal keyword with UnboundLocalError: local variable 'balance' referenced before assignment 下面的程序询问带有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)

But, below program does not give such error when inner function shift refers to lst before assignment as temp = lst[0] . 但是,当内部函数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)

How do I understand/compare these two scenarios? 我如何理解/比较这两种情况?

You are never assigning to lst , only to lst[index] . 您永远不会分配给lst ,而只会分配给lst[index] The two concepts are not quite the same thing. 这两个概念并不完全相同。

The line: 该行:

lst = some_other_value

would rebind the name lst to point to another object. 将重新绑定名称lst指向另一个对象。 The line: 该行:

lst[index] = some_other_value

alters the object referenced by the name lst , by binding a specific index in that sequence to something else. 通过将序列中的特定索引绑定到其他对象来更改名称lst引用的对象。 The name lst itself is never altered, so there is no ambiguity here as to what scope that name belongs in. 名称lst本身从未更改,因此在此名称所属的范围方面没有任何歧义。

In Python scoping, only binding operations on the name itself count. 在Python作用域中,只有对名称本身的绑定操作才算在内。 Binding operations are not just (direct) assignments, but also include function parameters, function and class definitions, import statements and targets for except .. as , with .. as and the target in for ... in loops. 绑定操作不仅是(直接)赋值,还包括函数参数,函数和类定义, import语句和目标, except .. aswith .. as和目标in for ... in循环外。 If a name is bound to in a given scope, it is considered local , in all other cases Python looks for the name in a parent scope, with the outermost scope being global . 如果在给定范围内绑定了名称,则将其视为本地名称 ,在所有其他情况下,Python会在父范围内查找名称,最外层的范围为global

Assignments to subscriptions (using [...] ) are not binding operations in this context. 在这种情况下,对订阅的分配(使用[...] )不是绑定操作。

See the Naming and binding section of the Python Execution Model documentation, as well as the Short Description of the Scoping Rules? 请参阅Python执行模型文档的命名和绑定部分 ,以及作用域规则简短说明? post. 帖子。

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

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