Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用循环中的变量在循环中生成函数会导致变量的阴影效应_Python_Variables_Scope_Composition - Fatal编程技术网

Python 使用循环中的变量在循环中生成函数会导致变量的阴影效应

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):

我想在循环中生成小函数,从循环中访问变量。然后我想一次编写并应用所有函数。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):
        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的类似问题。类似:啊,我理解,非常感谢。啊,我理解,非常感谢。