2

我刚刚在脚本中阅读了以下行:

fn = (len(sys.argv) > 2 and [sys.argv[2]] or ['test_out.jpg'])[0]

我真的不明白这里发生了什么。因此,将参数数量与 2 进行比较,然后是 or 语句。作者在做什么?这是一种好的编码风格吗?

4

3 回答 3

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'

UPDATEsys.argv[2]如果是空字符串,上面的代码将不起作用。这就是为什么原始代码使用[...][0]形式。因此,如果可能,请使用以下表格:

fn = sys.argv[2] if len(sys.argv) > 2 else 'test_out.jpg'
于 2013-10-02T11:54:51.547 回答
3

就我个人而言,我发现它的编码风格很糟糕,因为发生的事情并不那么明显(因此,你的问题)。

它在做什么:

  1. 查看是否sys.argv有超过 2 个项目
  2. 如果超过 2 项,则返回[sys.argv[2]]
  3. 否则,返回['test_out.jpg']
  4. 从上一个返回的项目(始终是一个列表)中,返回项目 0。

一个更简单的版本是:

fn = sys.argv[2:] and sys.argv[2] or 'test_out.jpg'

更易读的版本:

fn = sys.argv[2] if sys.argv[2:] else 'test_out.jpg'
于 2013-10-02T11:57:02.370 回答
0

and在某些情况下,or在 python 中就像短路一样。

在表达式x and y中,如果 x 的计算结果为False,那么甚至不需要查看 y,因为结果将是错误的。说,你想得到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则将采用 value ['test_out.jpg']

最后,括号用于然后使用[0]表达式中的 final 获取第零个索引。

总之:如果参数的数量是 2 或更多,则分配fnsys.argv[2],否则分配fn'test.out.jpg'

于 2013-10-02T12:05:42.490 回答