我有一个关于以下代码的问题。
如果不是,请原谅,我是一个python新手。
下面的代码在我的dodo.py中
def closed_over(par):
print("\n??? " + par)
if par == "bar":
return False
else:
return True
def task_bug():
for par in ("foo", "bar"):
print("par: " + par)
# closure!
exist_fn = lambda: closed_over(par)
print(exist_fn)
yield {
"name": par,
"actions": [["echo", "action:", par]],
"verbosity": 2,
"uptodate": [exist_fn]
}当我运行doit bug:foo时,我希望不会像(closed_over返回True)那样执行它,但是:
par: foo
<function task_bug.<locals>.<lambda> at 0x7f8926f9a560>
par: bar
<function task_bug.<locals>.<lambda> at 0x7f8926f9a5f0>
??? bar <- par should be foo
. bug:foo
action: foo <- echo was called正如您在上面看到的,yield外部的两个闭包是不同的函数对象,但是由于某些原因,uptodate总是调用相同的函数。
发布于 2019-12-01 16:12:15
你的问题是关于python闭包作用域(它作用域是变量,而不是值)……和doit无关。在Stack Overflow上可能有很多关于这个的问题:)
正如您在上面看到的,
外部的两个闭包是不同的函数对象,但是由于某些原因,最新的总是调用相同的函数。
不,它不会调用相同的闭包。问题是与参数相同的变量。
发布于 2019-12-03 03:38:27
事实证明,我假设python有动态作用域,而它实际上做的是词法作用域。
根据在野外的几个答案,这是实际有效的:
from functools import partial
def closed_over(par):
print("\n??? " + par)
if par == "bar":
return False
else:
return True
def task_bug():
"""Test a doit bug."""
for par in ("foo", "bar"):
print("par: " + par)
exist_fn = partial(closed_over, par)
print(exist_fn)
yield {
"name": par,
"actions": [["echo", "action:", par]],
"verbosity": 2,
"uptodate": [exist_fn]
}$ doit bug
par: foo
functools.partial(<function closed_over at 0x7f6ab3eb6cb0>, 'foo')
par: bar
functools.partial(<function closed_over at 0x7f6ab3eb6cb0>, 'bar')
??? foo
-- bug:foo
??? bar
. bug:bar
action: barhttps://stackoverflow.com/questions/59111807
复制相似问题