2

我想根据一些前提条件有条件地替换文件中的一行并写入新内容。我选择的方式是:

n_file = []
For line in file.getlines():
    n_file.append( line.replace(
            *("foo", "bar") if False else
            *("baz", "bam") if True else
            # ...
            *("", "") # no replacement
    ))
new_file.write(n_file)  

但我遇到了一个问题,我不明白。 问题是星号。每当函数的非第一个位置有星号时replace(),它都会给我一个语法错误,我完全不知道为什么。

你可以自己试试。在 Python 2 或 3 中也是如此。

def tf(a,b): print( str(a) +" "+ str(b) )

tf( *(1,1) if False else (2,2) if False else (3,3) )
# prints '3 3' as expec... intended

tf( *(1,1) if False else *(2,2) if False else *(3,3) )
# invalid syntax         ^

tf( (1,1) if False else (2,2) if False else (3,3) )
# missing 1 required positional argument: 'b'

虽然我找到了解决我的特定问题的方法。我仍然不明白为什么必须这样。我最好的猜测是它与扩展参数的位置有关,但它仍然无法解释为什么星号必须仅位于第一项

亲切的问候。

附言。这是我在这里的第一个问题,我不确定标题是否合适(或者如何专门称这个 if-thingy,发生在replace()-args 中)。寻找这个问题的答案很麻烦,所以如果你有更好的标题或标签建议,请告诉我。

4

1 回答 1

2

您需要用括号包裹整个级联的三元组,以便首先评估它们,然后继续解包表达式的结果。splat运算符位于括号之外:

tf( *((1,1) if False else (2,2) if False else (3,3)) ) #-> 3 3

进一步来说:

...
n_file.append( line.replace(
            **(("foo", "bar") if False else
               ("baz", "bam") if True else
                ...
               ("", "")) # no replacement
    ))

OTOH,当您像这样级联三元组时,代码变得非常不可读。if使用 vanilla子句,分配给变量然后解压缩变量会更具可读性。

于 2017-11-13T09:51:16.100 回答