What is the most Pythonic way to provide a fall-back value in an assignment?
在Perl中,能够分配一个对象通常是很好的,但是如果从中分配的变量是"undef",则指定一些回退值。例如:
1 2 3 | my $x = undef; my $y = 2; my $a = $x || $y; |
在此之后,
1 | $a == 2 |
在python中是否有一种简洁的方法来实现这一点,如果x值为none,或者将是一个完整的……
1 2 3 4 | if x is not None a = x else a = y |
…是实现这一目标的最Python的方式吗?
编辑:很抱歉,正如一些评论者所指出的,我并不是真的在谈论未定义的值,而是在Perl中的"undef",这实际上不是一回事。但最初的问题并没有说明这一点。
自2.5以来:
如果你只想退而不退:
1 | a = x if x is not None else y |
如果还想在空字符串、
1 | a = x if x else y |
或
1 | a = x or y |
对于未定义(从未定义,a.k.a.未绑定):
1 2 3 4 | try: a = x except NameError: a = y |
或者更具黑客风格(我不建议这么做,但它很短):
1 | a = vars().get('x',y) |
首先,你可以充分利用三元:
1 | a = y if x is None else x |
但它不能解决你的问题。您要做的是更紧密地实现:
1 2 3 4 | try: a = x except: a = y |
只是用Perl示例吹毛求疵:
1 | my $x = undef; |
此冗余代码可以缩短为:
1 | my $x; |
而下面的代码并没有做到你所说的那样:
1 | my $a = $x || $y; |
当$X为假时,它实际上将$Y分配给$A。假值包括
1 | my $a = $x // $y; |
我很确信没有"Python"的方法可以做到这一点,因为这不是Python的模式。控件不应到达优雅代码中未定义的变量引用。也有类似的想法是Python。最明显的是:
1 2 3 | def myRange(start, stop=None): start, stop = (0, start) if stop is None else (start, stop) ... |
重要的是,
也就是说,类似这样的东西可能会遵循这个前提,而不使用try-catch块。
1 | a = locals().get('x', y) |
我认为这会有帮助,因为问题归结为检查变量是否被定义:在Python中定义变量的简单方法?
有python的三元操作:
1 | a = x if x is not None else y |
2.5及以上版本。
重写的一种方法…
1 2 3 4 | if x is not None a = x else a = y |
..是:
1 2 3 4 5 6 | x = myfunction() if x is None: x = y print x |
或者,使用异常(可能更多的是python'y,这取决于代码在做什么——如果因为出错而返回none,则使用异常可能是正确的方法):
1 2 3 4 5 6 | try: x = myfunction() except AnException: x ="fallback" print x |
尽管如此,您的原始代码确实没有任何问题:
1 2 3 4 | if x is not None a = x else a = y |
它很长,但我发现阅读起来要比下面的一句话容易得多(而且要比Python的多):
1 2 | a = x if x is not None else y a = x or y |
大多数依赖于if语句的解决方案都不适用于x为0或负数的情况。
1 2 3 4 5 6 | >>> x = 0 >>> y = 2 >>> a = x or y >>> a 2 >>> |
如果您提前知道变量的名称,可以这样查找:
1 2 3 4 | if 'x' in dir(): a = x except: a =y |
不过,我觉得这个解决方案有点草率。我认为最好的方法是使用一个这样的试块:
1 2 3 4 | try: a = x else: a = y |
如果它是函数的参数,你可以这样做:
1 2 3 4 5 6 7 | def MyFunc( a=2 ): print"a is %d"%a >>> MyFunc() ...a is 2 >>> MyFunc(5) ...a is 5 |
[编辑]为投票者。对于解决方案,I/EL位是不必要的,只是添加以使结果清晰。编辑它来删除if语句,如果它使它更清晰?