问题:Python非本地语句

Python nonlocal语句有什么作用(在Python 3.0及更高版本中)?

官方Python网站上没有文档,help("nonlocal")也无法使用。

What does the Python nonlocal statement do (in Python 3.0 and later)?

There’s no documentation on the official Python website and help("nonlocal") does not work, either.


回答 0

比较一下,不使用nonlocal

x = 0
def outer():
    x = 1
    def inner():
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 0

对此,使用,其中inner()x是现在还outer()x

x = 0
def outer():
    x = 1
    def inner():
        nonlocal x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 2
# global: 0

如果要使用,它将绑定x到正确的“全局”值:

x = 0
def outer():
    x = 1
    def inner():
        global x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 2

Compare this, without using nonlocal:

x = 0
def outer():
    x = 1
    def inner():
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 0

To this, using , where inner()‘s x is now also outer()‘s x:

x = 0
def outer():
    x = 1
    def inner():
        nonlocal x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 2
# global: 0

If we were to use , it would bind x to the properly “global” value:

x = 0
def outer():
    x = 1
    def inner():
        global x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 2

回答 1

简而言之,它使您可以将值分配给外部(但非全局)范围内的变量。有关所有血腥细节,请参阅PEP 3104

In short, it lets you assign values to a variable in an outer (but non-global) scope. See PEP 3104 for all the gory details.


回答 2

谷歌搜索“ python nonlocal”发现了该提案PEP 3104,该提案完整描述了该语句背后的语法和推理。简而言之,它的作用与global声明完全相同,不同之处在于,它用于引用既不全局也不局部于函数的变量。

这是您可以执行此操作的简短示例。可以重写计数器生成器以使用它,以便它看起来更像是带有闭包的语言惯用法。

def make_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count
    return counter

显然,您可以将其编写为生成器,例如:

def counter_generator():
    count = 0
    while True:
        count += 1
        yield count

但是,尽管这是完全习惯用的python,但对于初学者来说,第一个版本似乎更加明显。通过调用返回的函数正确使用生成器是一个常见的困惑点。第一个版本显式返回一个函数。

A google search for “python nonlocal” turned up the Proposal, PEP 3104, which fully describes the syntax and reasoning behind the statement. in short, it works in exactly the same way as the global statement, except that it is used to refer to variables that are neither global nor local to the function.

Here’s a brief example of what you can do with this. The counter generator can be rewritten to use this so that it looks more like the idioms of languages with closures.

def make_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count
    return counter

Obviously, you could write this as a generator, like:

def counter_generator():
    count = 0
    while True:
        count += 1
        yield count

But while this is perfectly idiomatic python, it seems that the first version would be a bit more obvious for beginners. Properly using generators, by calling the returned function, is a common point of confusion. The first version explicitly returns a function.


回答 3

@ooboo:

它与源代码中的参考点“最接近”。这称为“词法作用域”,现在已经有40多年的历史了。

Python的类成员确实在名为的字典中,__dict__并且无法通过词法作用域来访问。

如果您未指定,nonlocal而是这样做x = 7,它将创建一个新的局部变量“ x”。如果您指定nonlocal,它将找到“最近”“ x”并分配给它。如果指定nonlocal并且没有“ x”,它将给您一条错误消息。

关键字global在我看来一直很奇怪,因为它会很乐意忽略除最外面的一个以外的所有其他“ x”。奇怪的。

@ooboo:

It takes the one “closest” to the point of reference in the source code. This is called “Lexical Scoping” and is standard for >40 years now.

Python’s class members are really in a dictionary called __dict__ and will never be reached by lexical scoping.

If you don’t specify nonlocal but do x = 7, it will create a new local variable “x”. If you do specify nonlocal, it will find the “closest” “x” and assign to that. If you specify nonlocal and there is no “x”, it will give you an error message.

The keyword global has always seemed strange to me since it will happily ignore all the other “x” except for the outermost one. Weird.


回答 4

help(’nonlocal’)nonlocal语句


    nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*

nonlocal语句使列出的标识符引用最近的封闭范围中的先前绑定的变量。这很重要,因为绑定的默认行为是首先搜索本地命名空间。该语句允许封装的代码在全局(模块)范围之外的本地范围之外重新绑定变量。

nonlocal与语句中列出的名称不同,语句中 列出的名称global必须引用封闭范围内的预先存在的绑定(不能明确确定应在其中创建新绑定的范围)。

nonlocal语句中列出的名称不得与本地范围内的现有绑定冲突。

也可以看看:

PEP 3104-访问外部作用域中
的名称nonlocal语句的规范。

相关帮助主题:全局,NAMESPACES

资料来源:Python语言参考

help(‘nonlocal’) The nonlocal statement


    nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*

The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope. This is important because the default behavior for binding is to search the local namespace first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope.

Names listed in a nonlocal statement, unlike to those listed in a global statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously).

Names listed in a nonlocal statement must not collide with pre- existing bindings in the local scope.

See also:

PEP 3104 – Access to Names in Outer Scopes
The specification for the nonlocal statement.

Related help topics: global, NAMESPACES

Source: Python Language Reference


回答 5

引用《Python 3参考》

非本地语句使列出的标识符引用最近的包围范围中的先前绑定的变量(全局变量除外)。

如参考文献中所述,如果有多个嵌套函数,则仅修改最近的封闭函数中的变量:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        x = 2
        innermost()
        if x == 3: print('Inner x has been modified')

    x = 1
    inner()
    if x == 3: print('Outer x has been modified')

x = 0
outer()
if x == 3: print('Global x has been modified')

# Inner x has been modified

“最近”变量可以相隔几个级别:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        innermost()

    x = 1
    inner()
    if x == 3: print('Outer x has been modified')

x = 0
outer()
if x == 3: print('Global x has been modified')

# Outer x has been modified

但是它不能是全局变量:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        innermost()

    inner()

x = 0
outer()
if x == 3: print('Global x has been modified')

# SyntaxError: no binding for nonlocal 'x' found

Quote from the Python 3 Reference:

The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals.

As said in the reference, in case of several nested functions only variable in the nearest enclosing function is modified:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        x = 2
        innermost()
        if x == 3: print('Inner x has been modified')

    x = 1
    inner()
    if x == 3: print('Outer x has been modified')

x = 0
outer()
if x == 3: print('Global x has been modified')

# Inner x has been modified

The “nearest” variable can be several levels away:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        innermost()

    x = 1
    inner()
    if x == 3: print('Outer x has been modified')

x = 0
outer()
if x == 3: print('Global x has been modified')

# Outer x has been modified

But it cannot be a global variable:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        innermost()

    inner()

x = 0
outer()
if x == 3: print('Global x has been modified')

# SyntaxError: no binding for nonlocal 'x' found

回答 6

a = 0    #1. global variable with respect to every function in program

def f():
    a = 0          #2. nonlocal with respect to function g
    def g():
        nonlocal a
        a=a+1
        print("The value of 'a' using nonlocal is ", a)
    def h():
        global a               #3. using global variable
        a=a+5
        print("The value of a using global is ", a)
    def i():
        a = 0              #4. variable separated from all others
        print("The value of 'a' inside a function is ", a)

    g()
    h()
    i()
print("The value of 'a' global before any function", a)
f()
print("The value of 'a' global after using function f ", a)
a = 0    #1. global variable with respect to every function in program

def f():
    a = 0          #2. nonlocal with respect to function g
    def g():
        nonlocal a
        a=a+1
        print("The value of 'a' using nonlocal is ", a)
    def h():
        global a               #3. using global variable
        a=a+5
        print("The value of a using global is ", a)
    def i():
        a = 0              #4. variable separated from all others
        print("The value of 'a' inside a function is ", a)

    g()
    h()
    i()
print("The value of 'a' global before any function", a)
f()
print("The value of 'a' global after using function f ", a)

回答 7

我对“非本地”语句的个人理解(并且对不起,因为我是Python和程序设计的新手)所以,“非本地”是在迭代函数中使用全局功能的一种方式,而不是代码本身。 。如果愿意,可以在函数之间进行全局声明。

My personal understanding of the “nonlocal” statement (and do excuse me as I am new to Python and Programming in general) is that the “nonlocal” is a way to use the Global functionality within iterated functions rather than the body of the code itself. A Global statement between functions if you will.


回答 8

具有“非本地”内部函数(即嵌套内部函数)的用户可以获取外部父函数的特定变量的读取和“ 写入 ”权限。非本地只能在内部函数中使用,例如:

a = 10
def Outer(msg):
    a = 20
    b = 30
    def Inner():
        c = 50
        d = 60
        print("MU LCL =",locals())
        nonlocal a
        a = 100
        ans = a+c
        print("Hello from Inner",ans)       
        print("value of a Inner : ",a)
    Inner()
    print("value of a Outer : ",a)

res = Outer("Hello World")
print(res)
print("value of a Global : ",a)

with ‘nonlocal’ inner functions(ie;nested inner functions) can get read & ‘write‘ permission for that specific variable of the outer parent function. And nonlocal can be used only inside inner functions eg:

a = 10
def Outer(msg):
    a = 20
    b = 30
    def Inner():
        c = 50
        d = 60
        print("MU LCL =",locals())
        nonlocal a
        a = 100
        ans = a+c
        print("Hello from Inner",ans)       
        print("value of a Inner : ",a)
    Inner()
    print("value of a Outer : ",a)

res = Outer("Hello World")
print(res)
print("value of a Global : ",a)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。