函数调用中的条件参数扩展

时间:2017-11-13 09:49:25

标签: python if-statement conditional argument-unpacking

我想有条件地替换文件中的单行,具体取决于某些前提条件并写入新内容。 我选择的方式是:

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'

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

亲切的问候。

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

1 个答案:

答案 0 :(得分:2)

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

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,当您像这样级联三元时,代码变得非常难以理解。使用vanilla if子句,分配给变量然后解压缩变量会更具可读性。