我已经在Python中看到并使用了嵌套函数,它们与闭包的定义相匹配.那他们为什么叫nested functions而不是closures?
嵌套函数是不是闭包,因为它们不被外部世界使用?
更新:我正在阅读关于闭包的内容,这让我想到了关于Python的这个概念.我在下面的评论中搜索并找到了某人提到的文章,但我无法完全理解该文章中的解释,所以这就是我提出这个问题的原因.
以下代码在Python 2.5和3.0中按预期工作:
a, b, c = (1, 2, 3)
print(a, b, c)
def test():
print(a)
print(b)
print(c) # (A)
#c+=1 # (B)
test()
Run Code Online (Sandbox Code Playgroud)
但是,当我取消注释行(B)时,我得到了UnboundLocalError: 'c' not assigned一行(A).的值a和b被正确地打印.这让我感到困惑,原因有两个:
为什么在行(A)处抛出运行时错误,因为后面的行(B)语句?
为什么变量a和b打印符合预期,同时c引发错误?
我能想到的唯一解释是,赋值创建了一个局部变量,即使在创建局部变量之前,它也优先于"全局"变量.当然,变量在存在之前"窃取"范围是没有意义的.cc+=1c
有人可以解释一下这种行为吗?
我正在尝试在Python 2.6中实现一个闭包,我需要访问一个非局部变量,但似乎这个关键字在python 2.x中不可用.如何在这些版本的python中访问闭包中的非局部变量?
给出以下代码:
def A() :
b = 1
def B() :
# I can access 'b' from here.
print( b )
# But can i modify 'b' here? 'global' and assignment will not work.
B()
A()
Run Code Online (Sandbox Code Playgroud)
对于B()函数变量中的代码,b在外部作用域中,但不在全局作用域中.是否可以b从B()函数内修改变量?当然我可以从这里读取它print(),但是如何修改呢?
在下面的Python代码中,我得到了一个UnboundLocalError.据我所知,局部函数共享包含函数的局部变量,但这似乎不是这里的情况.我认识到a在这种情况下这是一个不可变的值,但这应该不是问题.
def outer():
a = 0
def inner():
a += 1
inner()
outer()
Run Code Online (Sandbox Code Playgroud)
看起来内部函数已经收到了父函数中所有引用的副本,因为UnboundLocalError如果值的值a被包装在一个可变类型中,我就不会得到异常.
有人能够澄清这里的行为,并指出相应的Python文档吗?
我正在学习编程语言的概念。
我在 python 语法中发现了术语“nonlocal”。
python中的nonlocal是什么意思?
python variables programming-languages global-variables python-nonlocal
我想测试在这个问题的答案中使用的非本地语句的示例:
def outer():
x = 1
def inner():
nonlocal x
x = 2
print("inner:", x)
inner()
print("outer:", x)
Run Code Online (Sandbox Code Playgroud)
但是当我尝试加载此代码时,我总是会收到语法错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "t.py", line 4
nonlocal x
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
有没有人知道我在这里做错了什么(我得到的每个例子的语法错误,包含nonlocal).
我怀疑我想做的事情在Python中不是那么干净.以下是一些相互调用的嵌套函数.(通常,它们不必是词法范围的,但需要动态地相互调用.)
def outer() :
s_outer = "outer\n"
def inner() :
s_inner = "inner\n"
do_something()
inner()
Run Code Online (Sandbox Code Playgroud)
现在,当我打电话do_something(),然后我想访问的调用函数的变量进一步向上调用堆栈,在这种情况下s_outer和s_inner.
不幸的是,nonlocal这里的关键字只有在我定义函数do_something()内部时才有帮助inner().但是,如果我在同一级别定义它,outer()则nonlocal关键字将不起作用.
但是,我想do_something()从各种其他函数调用,但始终在各自的上下文中执行它并访问它们各自的范围.
感觉顽皮我然后写了一个小的访问者,我可以从do_something()这里调用:
def reach(name) :
for f in inspect.stack() :
if name in f[0].f_locals : return f[0].f_locals[name]
return None
Run Code Online (Sandbox Code Playgroud)
然后
def do_something() :
print( reach("s_outer"), reach("s_inner") )
Run Code Online (Sandbox Code Playgroud)
工作得很好.
我的两个问题是这些
有没有更好的方法来解决这个问题?(除了将各自的数据包装成dicts并明确地将这些dicts传递给do_something())
是否有更优雅/缩短的方式来实现该reach()功能?
干杯!
我有一个非常基本的问题.
假设我调用一个函数,例如,
def foo():
x = 'hello world'
Run Code Online (Sandbox Code Playgroud)
如何让函数以这样的方式返回x,我可以将它用作另一个函数的输入或者在程序体内使用变量?
当我使用return并在另一个函数中调用该变量时,我得到一个NameError.
这个问题是关于Python变量范围的问题的后续问题.其他问题q1,q2和答案可以在SO上找到,甚至更多.官方Python文档和PEP 3104应该解释细节,但它们对我来说似乎并不完全不言自明.
我试图解决的主题是重构包含nonlocal/ global通过在一级层次结构上/下移动该代码的代码.
我不明白的是Python参考中这句话的含义:
与全局语句中列出的名称不同,非本地语句中列出的名称必须引用封闭范围中的预先存在的绑定(无法明确确定应创建新绑定的范围).
给出以下全局范围的代码:
var = 0
def outer():
global var # line A
var = 1
def inner():
nonlocal var # line B
var = 2
print('inner:', var)
inner()
print('outer:', var)
outer()
print('main:', var)
Run Code Online (Sandbox Code Playgroud)
执行会引发错误:
SyntaxError: no binding for nonlocal 'var' found
Run Code Online (Sandbox Code Playgroud)
代码可以工作(当然,如果任何一行A被注释掉,则会有不同的语义:
inner: 2
outer: 2
main: 0
Run Code Online (Sandbox Code Playgroud)
或B行被注释掉:
inner: 2
outer: 1
main: 1
Run Code Online (Sandbox Code Playgroud)
但是,在上面的例子中,并且因为nonlocal应该将var绑定到"封闭范围",我会预期A行将外部/ …
python ×9
closures ×3
function ×2
python-3.x ×2
scope ×2
variables ×2
binding ×1
local ×1
model ×1
python-2.7 ×1
python-2.x ×1
syntax-error ×1