我刚刚在脚本中阅读了以下一行:
fn = (len(sys.argv) > 2 and [sys.argv[2]] or ['test_out.jpg'])[0]
我真的不知道这里发生了什么。所以有一个参数的数量与2的比较,然后是一个或语句。作者在做什么并且它是一种很好的编码风格?
答案 0 :(得分:5)
fn = (len(sys.argv) > 2 and [sys.argv[2]] or ['test_out.jpg'])[0]
就像:
fn = ([sys.argv[2]] if len(sys.argv) > 2 else ['test_out.jpg'])[0]
简单陈述:
if len(sys.argv) > 2:
fn = [sys.argv[2]][0]
else:
fn = ['test_out.jpg'][0]
正如您所看到的,[...][0]
有点多余。因此原始声明可以替换如下:
fn = len(sys.argv) > 2 and sys.argv[2] or 'test_out.jpg'
更新如果sys.argv[2]
为空字符串,则上述代码无效。这就是原始代码使用[...][0]
形式的原因。因此,如果可能,请使用以下表格:
fn = sys.argv[2] if len(sys.argv) > 2 else 'test_out.jpg'
答案 1 :(得分:3)
就我个人而言,我觉得编码风格很糟糕,因为发生的事情并不那么明显(因此,你的问题)。
它在做什么:
sys.argv
是否包含超过2件商品[sys.argv[2]]
['test_out.jpg']
更简单的版本是:
fn = sys.argv[2:] and sys.argv[2] or 'test_out.jpg'
更易阅读的版本:
fn = sys.argv[2] if sys.argv[2:] else 'test_out.jpg'
答案 2 :(得分:0)
and
和or
在某些情况下就像短路一样。
在表达式x and y
中,如果x的计算结果为False
,则无需查看y,因为结果将为false。比如,你想获得sys.argv[2]
,但只有在有足够的参数的情况下。然后你可以这样做:
len(sys.argv)> 2和[sys.argv [2]]
因此,如果sys.argv
的长度为2或更短,则len(sys.argv) > 2
将评估为false,并且不会评估sys.argv[2]
(因此不会遇到IndexError
)
同样,在表达式x or y
中,仅当x
评估为False
时才会评估y
。因此,如果参数的数量小于或等于2,则fn
将采用值['test_out.jpg']
。
最后,括号用于使用表达式中的最终[0]
获取第零个索引。
总结:如果参数数量为2或更多,则将fn
分配给sys.argv[2]
,否则将fn
分配给'test.out.jpg'
。