2012-01-30 81 views
5

可能重複:
Python conditional assignment operatorPython的等效的Perl /紅寶石||的=

道歉這樣一個簡單的問題,但使用Google ||=不是非常有用,是)

在Python和Ruby和Perl中存在的||=語句中是否有等價物?

例如:

foo = "hey" 
foo ||= "what" # assign foo if it's undefined 
# foo is still "hey" 

bar ||= "yeah" 
# bar is "yeah" 

而且什麼是這樣的事情的總稱?有條件的分配是我的第一次猜測,但Wikipedia page不是我想到的。

+0

是的,它似乎是一個重複。感謝Adam! – 2012-01-30 05:23:34

+2

'$ foo || =「如果它已經是* false *,將重新分配'$ foo'。當然'undef'是錯誤的,但是零和空字符串也是如此。要重新分配一個未定義的值,請使用斜槓,而不是'$ foo // =「what」 – Borodin 2012-01-30 05:28:35

+0

請注意,在Perl 5.10中添加了「//」(及其擴展名,「// =」)。如果你仍然堅持5.8.x,你將無法使用''// ='(如果可能的話,你應該認真考慮升級)。 – 2012-01-30 14:40:49

回答

6

更詳細的一點點位,但最簡單的是

foo = "hey" 
foo = foo or "what" 
#foo is still "hey" 

bar = None 
bar = bar or "yeah" 
#bar is "yeah" 

您也可以使用三元運算

bar = None 
bar = bar if bar else "yeah" 

不過,如果我理解你,||=分配了以前沒有的變量定義,沒有投訴?我不知道。

要做到這一點在局部範圍內,這個醜小鴨可以工作

bar = locals()['bar'] if 'bar' in locals() else 'yeah' 

編輯:

剛看到重複的,它有很多的解決方案,以及:)對於那些懶得看,它們還包括在一個更好的變種我的最後一個

foo = foo if 'foo' in locals() else 'hey' 

但是這不會對不確定的變量的工作,只falsy值將被取代,不確定將引發NameError。這下一個會,OTOH,只爲不確定的工作,並始終保持相同的預先存在falsy值,作爲@Borodin說是像//=在Perl

foo = locals().get('foo','hey') 

,當然,有人用一個例外:(

try: 
    v 
except NameError: 
    v = 'bla bla' 
+0

否,'|| ='將重新分配一個變量,如果它是'false'。看到我對這個問題的評論。你爲什麼會期待投訴? – Borodin 2012-01-30 05:30:01

+0

感謝您的回覆,起初我沒有注意到細微差別。它需要'bar = None'來工作,否則會拋出一個'NameError'。對於相同的行爲,你需要你的locals()['bar']'snippet。再次感謝:) – 2012-01-30 05:31:04

+0

@borodin我不是Rubyist,我只是用它來做像廚師這樣愚蠢的東西。我的意思是我不知道Ruby中的'undef'是錯誤的,因爲在Python中情況並非如此(未定義的引用會拋出異常)。無論如何,感謝您的評論,我學到了一些東西:) – 2012-01-30 05:35:35

1

不知道的名字,我能想出的最好的是:在Python

>>> a = 'foo' 
>>> a = 'a' in locals() and a or 'what' 
>>> a 
'foo' 
>>> b = 'b' in locals() and b or 'yeah' 
>>> b 
'yeah' 
2

你幾乎從來都沒有定義的變量,當你經常這樣做意味着你有m個發生錯誤。但是,方便起見,大多數通常用作默認值(空容器,零長度字符串,零和None)的值在Python中是「虛假」的,所以您有時候會看到類似這樣的東西,它利用了Python中的布爾運算符的工作:

name = name or "Guido" # if name is empty, set it to "Guido" 
numb = numb or 42  # if numb is zero, set it to 42 

這部作品的原因是Python的停止評估or如果第一個參數是「truthy,」這就是所謂短路,並在這兩種情況下返回實際的參數,而不是其結果僅爲TrueFalse。因此,如果name是「吉姆」,那麼"Jim" or "Guido"的計算結果爲"Jim",因爲"Jim"是非零長度的字符串,因此爲「truthy」。

當然,如果您不知道所處理的值的類型和/或「falsy」值是否爲有效值,那麼這種方法效果不佳。然而,它的工作原理相當不錯的東西像配置文件和raw_input()其中一個缺失值會返回一個空字符串:在一個字典項時,

name = raw_input("What is your name? ") or "Guido" 

另一種常見的成語使用。如果變量不在字典中,字典類的get()方法可讓您指定要使用的默認值。

name = values.get("name", "Guido") 

這可以當你的功能已經通過使用**kwargs約定關鍵字參數一起使用。您可以也有變數使用它,作爲globals()locals()功能範圍返回,分別,所有的全局或局部變量,目前作爲詞典:

name = locals().get("name", "Guido") 

然而,正如我說的,你很少會擁有實際上是Python中未定義的變量。例如,在Web框架的情況下,您會將查詢字符串參數作爲字典傳遞,並且可以使用字典的.get()方法。

在罕見的情況下,名稱實際上不存在(例如,您的配置文件是Python語法,並且您將它作爲Python模塊導入而不是解析它,並且希望用戶可以省略一些值...或者同樣古怪的),那麼你可以使用getattr(),這(如字典的.get())接受默認值:

import config 
name = getattr(config, "name", "Guido") # rather than just name.config 

,還是讓它拋出一個NameError並抓住它。