2009-04-20 23 views
14

在Perl中,能夠分配一個對象通常很好,但如果被賦值的變量是'undef',則指定一些後退值。例如:在任務中提供回退價值的最Python方法是什麼?

my $x = undef; 
my $y = 2; 
my $a = $x || $y; 

在此之後,

$a == 2 

有一種簡潔的方式在Python實現這一點,如果x的值是無,或將全上......

if x is not None 
    a = x 
else 
    a = y 

......成爲實現這一目標最符合Pythonic的方法?

編輯:道歉,正如一些評論者指出的那樣,我並沒有真正談論未定義的值,而是Perl中的'undef',這不是真的是一回事。但最初措辭的問題沒有說清楚。

+2

請記住,「如果變量被賦值是未定義的」是錯誤的。 「如果分配的變量是假的」更接近真相。 – innaM 2009-04-20 13:19:37

+1

要跟進Manni的評論:如果您可以依賴Perl 5.10或更高版本,最好使用定義的或運算符「//」。 (不是說這對你如何在Python中執行操作有任何影響。) – 2009-04-20 14:42:57

回答

26

自2.5:

如果要回落只在無

a = x if x is not None else y 

如果你想回來也落在空字符串,false0等:

a = x if x else y 

a = x or y 

至於不確定的(因爲從來沒有定義,又名不綁定):

try: 
    a = x 
except NameError: 
    a = y 

或略偏hackish的(我不是真的建議,但它的簡稱):

a = vars().get('x',y) 
+0

比我的更好的方法... – Greg 2009-04-20 13:14:29

+0

hm,所以x的定義畢竟是:/ – SilentGhost 2009-04-20 13:18:27

+0

@greg:它不比你的更好,但它同樣錯了 – SilentGhost 2009-04-20 13:37:46

1

有Python的三元操作:

a = x if x is not None else y 

可用於2.5及以上。

-1

如果它是一個參數傳遞給函數,你可以這樣做:

def MyFunc(a=2): 
    print "a is %d"%a 

>>> MyFunc() 
...a is 2 
>>> MyFunc(5) 
...a is 5 

[編輯]對於downvoters ..的的if/else位是不必要的解決方案 - 只要加入使結果明確。編輯它以刪除if語句,如果這使得它更清晰?

5

首先,你可以做你完全與三元:

a = y if x is None else x 

但它不能解決您的問題。你想要做什麼用更加緊密地執行:

try: 
    a = x 
except: 
    a = y 
0

大部分的解決方案依靠if語句不爲其中x爲0或負的情況下工作的。

>>> x = 0 
>>> y = 2 
>>> a = x or y 
>>> a 
2 
>>> 

如果你知道時間提前的變量的名稱,你可以尋找像這樣:

if 'x' in dir(): 
    a = x 
except: 
    a =y 

但是,這種解決方案似乎有點草率的給我。我認爲最好的方法是使用try except塊,像這樣:

try: 
    a = x 
else: 
    a = y 
3

我很相信,沒有「Python化」的方式來做到這一點,因爲這不是是Python的一種模式。控制不應該在優雅的代碼中達到未定義的變量引用。有類似的思想是pythonic。最明顯的:

def myRange(start, stop=None): 
    start, stop = (0, start) if stop is None else (start, stop) 
    ... 

什麼重要的是,stop在範圍界定,但主叫方沒有明確地傳遞,只知道它已採取它的默認值,改變的參數的語義,這在效果會導致第一個參數是可選的而不是第二個參數,即使語言不允許沒有這個聰明的技巧。

也就是說,像這樣的東西可能會遵循前提條件而不使用try-catch塊。

a = locals().get('x', y) 
4

只是一些挑剔你的Perl例如:

my $x = undef; 

這種冗餘代碼可以簡化爲:

my $x; 

而下面的代碼沒有你說的它做什麼:

my $a = $x || $y; 

Th當$ x是false時,實際上是將$ y分配給$ a。假值包括undef,零和空字符串。只爲definedness測試,你可以做以下(像Perl 5.10):

my $a = $x // $y; 
0

一種方式重寫......

if x is not None 
    a = x 
else 
    a = y 

..是:

​​

或者,使用異常(可能更多Python'y,取決於什麼代碼做什麼 - 如果它返回None,因爲有錯誤,使用一個例外可能是正確的做法):

try: 
    x = myfunction() 
except AnException: 
    x = "fallback" 

print x 

所有這一切說,實在是沒有什麼錯,你原來的代碼:

if x is not None 
    a = x 
else 
    a = y 

它的長,但我覺得更容易閱讀(更符合Python)比任何的弗洛翼單線:

a = x if x is not None else y 
a = x or y 
相關問題