我想根据一些前提条件有条件地替换文件中的一行并写入新内容。 我选择的方式是:
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 中)。
寻找这个问题的答案很麻烦,所以如果你有更好的标题或标签建议,请告诉我。
您需要用括号将整个三元组级联括起来,以便首先对它们进行求值,然后继续解包表达式的结果。 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
子句会更具可读性,分配给一个变量,然后解压该变量。
函数定义
def tf(a, b):
print(str(a) + " " + str(b))
该函数有 2 个参数,
a
和 b
。
第一个案例
函数调用
tf(*(1,1) if False else (2,2) if False else (3,3))
会起作用,因为,
首先执行表达式
(1,1) if False else (2,2) if False else (3,3)
,结果为(3,3)
。
然后函数调用变成
tf(*(3,3))
,就像将星号参数传递给函数一样。
这样就会匹配到函数定义,并且执行函数,也就是
3 3
。
第二种情况
tf(*(1,1) if False else *(2,2) if False else *(3,3))
这会失败,因为,
*(1,1) if False else *(2,2) if False else *(3,3)
是无效表达式。第三种情况
tf((1,1) if False else (2,2) if False else (3,3))
这会失败,因为
表达式
(1,1) if False else (2,2) if False else (3,3)
将计算为 (3,3)
,这是一个元组。
此结果是单个对象,而函数签名要求传递 2 个参数。
因此
(3, 3)
将被传递为 a
。缺少 b
的值,并且它是必需的位置参数,因此出现错误 missing 1 required positional argument: 'b'