问题:Python非本地语句
Python nonlocal
语句有什么作用(在Python 3.0及更高版本中)?
官方Python网站上没有文档,help("nonlocal")
也无法使用。
回答 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
回答 1
简而言之,它使您可以将值分配给外部(但非全局)范围内的变量。有关所有血腥细节,请参阅PEP 3104。
回答 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,但对于初学者来说,第一个版本似乎更加明显。通过调用返回的函数正确使用生成器是一个常见的困惑点。第一个版本显式返回一个函数。
回答 3
@ooboo:
它与源代码中的参考点“最接近”。这称为“词法作用域”,现在已经有40多年的历史了。
Python的类成员确实在名为的字典中,__dict__
并且无法通过词法作用域来访问。
如果您未指定,nonlocal
而是这样做x = 7
,它将创建一个新的局部变量“ x”。如果您指定nonlocal
,它将找到“最近”“ x”并分配给它。如果指定nonlocal
并且没有“ x”,它将给您一条错误消息。
关键字global
在我看来一直很奇怪,因为它会很乐意忽略除最外面的一个以外的所有其他“ x”。奇怪的。
回答 4
help(’nonlocal’)
nonlocal
语句nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*
该
nonlocal
语句使列出的标识符引用最近的封闭范围中的先前绑定的变量。这很重要,因为绑定的默认行为是首先搜索本地命名空间。该语句允许封装的代码在全局(模块)范围之外的本地范围之外重新绑定变量。
nonlocal
与语句中列出的名称不同,语句中 列出的名称global
必须引用封闭范围内的预先存在的绑定(不能明确确定应在其中创建新绑定的范围)。
nonlocal
语句中列出的名称不得与本地范围内的现有绑定冲突。也可以看看:
PEP 3104-访问外部作用域中
的名称nonlocal
语句的规范。相关帮助主题:全局,NAMESPACES
资料来源:Python语言参考
回答 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
回答 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)
回答 7
我对“非本地”语句的个人理解(并且对不起,因为我是Python和程序设计的新手)所以,“非本地”是在迭代函数中使用全局功能的一种方式,而不是代码本身。 。如果愿意,可以在函数之间进行全局声明。
回答 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)