“nonlocal” 是什么意思? 在 Python 3 中做什么?

发布于 2024-08-02 01:05:54 字数 497 浏览 11 评论 0原文

nonlocal 在 Python 3.x 中做什么?


要关闭OP需要nonlocal并且没有意识到的调试问题,请使用是否可以修改python 中的变量位于外部范围,但不是全局范围? 相反。

尽管 Python 2 是 自 2020 年 1 月 1 日起正式不再支持,如果由于某种原因您被迫维护 Python 2.x 代码库并且需要与 nonlocal 等效的代码库code>,请参阅Python 2.x 中的非本地关键字

What does nonlocal do in Python 3.x?


To close debugging questions where OP needs nonlocal and doesn't realize it, please use Is it possible to modify variable in python that is in outer, but not global, scope? instead.

Although Python 2 is officially unsupported as of January 1, 2020, if for some reason you are forced to maintain a Python 2.x codebase and need an equivalent to nonlocal, see nonlocal keyword in Python 2.x.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

一萌ing 2024-08-09 01:05:54

比较一下,不使用 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

对此,使用 nonlocal,其中 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

如果我们要使用 global,它将把 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 nonlocal, 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 global, 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
三生池水覆流年 2024-08-09 01:05:54

简而言之,它允许您为外部(但非全局)范围内的变量赋值。 请参阅 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.

撑一把青伞 2024-08-09 01:05:54

谷歌搜索“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.

拿命拼未来 2024-08-09 01:05:54

它采用与源代码中的参考点“最接近”的一个。
这称为“词汇范围”,并且已成为标准 40 年以上。

Python 的类成员实际上位于名为 __dict__ 的字典中,并且永远不会通过词法作用域来访问。

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

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

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.

蓝天 2024-08-09 01:05:54

帮助('非本地')
nonlocal 语句

<小时>

 nonlocal_stmt ::=“非本地”标识符(“,”标识符)* 
  

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

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

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

另请参阅:

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

相关帮助主题:全局、命名空间

来源: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

淡紫姑娘! 2024-08-09 01:05:54

引自 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
陌路终见情 2024-08-09 01:05:54
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)
兰花执着 2024-08-09 01:05:54

我个人对“非局部”声明的理解(请原谅,因为我对 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.

笨死的猪 2024-08-09 01:05:54

文档如下所示:

非本地语句导致列出的标识符引用
先前在最近的封闭范围中绑定的变量,不包括
全局变量。 ...

例如,inner() 中的nonlocal foo 可以访问非局部变量foo = 10middle() 中,但不是outer() 中的非局部变量 foo = 5> outer() 外部的全局变量 foo = 0 如下所示:

foo = 0 # <- ✖
def outer():
    foo = 5 # <- ✖
    def middle():
        foo = 10 # <- 〇
        def inner():
            nonlocal foo # Here
            foo += 1
            print(foo) # 11
        inner()
    middle()
outer()

The documentation says below:

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

So for example, nonlocal foo in inner() can access the non-local variable foo = 10 in middle() but not the non-local variable foo = 5 in outer() or the global variable foo = 0 outside outer() as shown below:

foo = 0 # <- ✖
def outer():
    foo = 5 # <- ✖
    def middle():
        foo = 10 # <- 〇
        def inner():
            nonlocal foo # Here
            foo += 1
            print(foo) # 11
        inner()
    middle()
outer()
雪若未夕 2024-08-09 01:05:54

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

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)
蓝色星空 2024-08-09 01:05:54

如果普通脚本中有普通函数,则可能有两组变量:

  • 顶层函数外部的变量(全局),
  • 函数内部定义的变量(局部) >)。

如果您在另一个函数(内部函数)内部定义了一个函数,则可能有三组变量:

  • 位于顶层的变量( global
  • 内部函数中的那些(local
  • 介于两者之间的那些:在外部函数中定义并且对于外部函数来说是局部的,但对于内部函数来说是相对全局的(local ) >nonlocal)

如果您有内部嵌套函数,并且您需要访问外部函数中定义的变量,那么非局部变量就有意义。

If you have a normal function in a normal script, you have potentially two sets of variables:

  • those outside the function at the top level (global)
  • those defined inside the function (local).

If you have a function defined inside another function (an inner function), you have potentially three sets of variables:

  • those at the top level (global)
  • those in the inner fuction (local)
  • those in between: defined in the outer function and local to the outer function, but relatively global to the inner function (nonlocal)

Nonlocal variables are meaningful if you have inner, nested functions, where you need to access variables defined in the outer function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文