Python 使用循环中的变量在循环中生成函数会导致变量的阴影效应
我想在循环中生成小函数,从循环中访问变量。然后我想一次编写并应用所有函数。MWE看起来是这样的:Python 使用循环中的变量在循环中生成函数会导致变量的阴影效应,python,variables,scope,composition,Python,Variables,Scope,Composition,我想在循环中生成小函数,从循环中访问变量。然后我想一次编写并应用所有函数。MWE看起来是这样的: from functools import reduce def compose(*funcs): return lambda x: reduce(lambda y, f: f(y), reversed(funcs), x) def replace_values_by_type(text, values, types) -> str: def peek(x):
from functools import reduce
def compose(*funcs):
return lambda x: reduce(lambda y, f: f(y), reversed(funcs), x)
def replace_values_by_type(text, values, types) -> str:
def peek(x):
print('peek:', x)
return x
replacements = [lambda txt: peek(peek(txt).replace(peek(val), f'<{peek(typ)}>')) for val, typ in zip(values, types)]
replace = compose(*replacements)
text_with_replacements = replace(text)
print(values)
print(types)
print(text)
print(text_with_replacements)
print()
return text_with_replacements
replace_values_by_type('this is a test sentence', ['is', 'test'], ['A', 'B'])
顺便说一句,为了解决这个问题,我还编写了如下函数:
def replace_values_by_type(text, values, types) -> str:
replacements = []
for val, typ in zip(values, types):
def f(txt):
return txt.replace(val, f'<{typ}>')
replacements.append(f)
text_with_replacements = text
for f in replacements:
text_with_replacements = f(text_with_replacements)
return text_with_replacements
print(replace_values_by_type('this is a test sentence', ['is', 'test'], ['A', 'B']))
def将值替换为类型(文本、值、类型)->str:
替换=[]
对于val,zip中的类型(值、类型):
def f(txt):
返回txt.replace(val,f“”)
替换。附加(f)
text_与_替换=text
对于替换中的f:
text_with_replacements=f(text_with_replacements)
返回包含替换内容的文本
打印(将_值_替换为_类型('这是一个测试句子',['is','test'],['a','B']))
问题仍然是一样的。列表理解创建的所有闭包都在同一个变量范围内,循环中只有
val
和typ
变量的一个实例。稍后调用闭包时,变量的值来自上一次迭代
您需要在每个迭代的唯一范围内生成闭包。一种方法是编写一个单独的函数返回闭包,因为每个函数都建立一个新的作用域
def replacer(val, typ):
return lambda txt: peek(peek(txt).replace(peek(val), f'<{peek(typ)}>'))
replacements = [replacer(val, typ) for val, typ in zip(values, types)]
def更换器(val,典型):
返回lambda txt:peek(peek(txt).替换(peek(val),f“”)
replacements=[replacer(val,typ)表示val,zip中的typ(值,类型)]
列表理解创建的所有闭包都在相同的变量范围内,循环中只有一个
val
和typ
变量实例。稍后调用闭包时,变量的值来自上一次迭代
您需要在每个迭代的唯一范围内生成闭包。一种方法是编写一个单独的函数返回闭包,因为每个函数都建立一个新的作用域
def replacer(val, typ):
return lambda txt: peek(peek(txt).replace(peek(val), f'<{peek(typ)}>'))
replacements = [replacer(val, typ) for val, typ in zip(values, types)]
def更换器(val,典型):
返回lambda txt:peek(peek(txt).替换(peek(val),f“”)
replacements=[replacer(val,typ)表示val,zip中的typ(值,类型)]
我认为列表理解只是为迭代变量建立了一个作用域,而不是每个迭代都有一个作用域。@Bramar所以每次迭代都会被覆盖,是吗?我试图在
val
和typ
内部f
上使用deepcopy,因为我怀疑这一点。但这也没用,没什么可模仿的。问题在于变量val
和typ
的使用——所有lambda都引用相同的变量,并且它们包含循环中的最后一个值。在JavaScript中,这被称为“臭名昭著的循环问题”。我试图找到关于Python的类似问题。类似:我认为列表理解只是为迭代变量建立了一个作用域,而不是每个迭代都有一个作用域。@Bramar所以每次迭代都会被覆盖,是吗?我试图在val
和typ
内部f
上使用deepcopy,因为我怀疑这一点。但这也没用,没什么可模仿的。问题在于变量val
和typ
的使用——所有lambda都引用相同的变量,并且它们包含循环中的最后一个值。在JavaScript中,这被称为“臭名昭著的循环问题”。我试图找到关于Python的类似问题。类似:啊,我理解,非常感谢。啊,我理解,非常感谢。