簡體   English   中英

Python相當於Ruby的|| =

[英]Python's equivalent of Ruby's ||=

要檢查變量是否存在,並且如果退出,請使用原始值,否則,使用分配的新值。 在ruby中,它是var ||= var_new

如何在python中編寫它?

PS:我不知道||=name ,我根本無法在Bing中搜索它。

我認為那些不確定條件賦值運算符( ||= )是什么的人還有一些混淆,以及對如何在Ruby中生成變量的一些誤解。

每個人都應該閱讀這篇關於這個主題的文章 TLDR報價:

一個常見的誤解是|| = b等於a = a || b,但它的行為類似於|| a = b

在a = a ||中 b,a在每次運行時由語句設置為某個值,而使用|| a = b,a僅在a邏輯上為假(即,如果它為零或假)時才設置,因為|| 是'短路'。 也就是說,如果是||的左側 比較是真的,沒有必要檢查右側。

另一個非常重要的說明:

......變量賦值,即使沒有運行,也會立即將該變量召喚出來。

# Ruby
x = 10 if 2 == 5
puts x

即使第一行不會運行,x也將存在於第二行,並且不會引發異常。

這意味着Ruby絕對會確保在任何正確的條件發生之前有一個值的變量容器。 ||=如果不分配a 沒有定義 ,它分配如果a是falsy(再次, falsenil - nil是Ruby中的默認值虛無 ),而保證a 定義。

這對Python意味着什么?

好吧,如果定義了a ,則以下內容:

# Ruby
a ||= 10

實際上相當於:

# Python
if not a:
    a = 10

而以下內容:

# Either language
a = a or 10

很接近,但它總是分配一個值,而前面的例子沒有。

如果a未定義,則整個操作更接近:

# Python
a = None
if not a:
    a = 10

因為當a未定義時, a ||= 10所做的非常明確的例子是:

# Ruby
if not defined? a
    a = nil
end

if not a
    a = 10
end

在一天結束時, ||=運算符不能以任何類型的'Pythonic'方式完全轉換為Python,因為它依賴於Ruby中的底層變量生成。

在python中沒有特別優雅的方式,因為讓自己陷入不知道變量是否存在的情況並不是特別優雅。 但是,這似乎最接近:

try:
    var
except NameError:
    var = var_new

我不熟悉ruby中的||=運算符,但是根據你所描述的,這個塊應該具有正確的行為。 也就是說,如果它是一個已經存在的變量,我們將var保留為var_new否則我們將其設置為var_new

這大概是您想要的:

var = var or var_new

Python對“不存在”變量的規則非常嚴格; 如果先前未分配var則會拋出異常。 但是,如果var 計算結果為false ,則會收到var_new的值。

我說這是“慣用的你想要的東西”,因為在Python中這種事物的慣用較大的結構是這樣的:

var1 = None
var2 = None
var3 = None

# ... code here that may or may not set var1 through var3 ...

var1 = var1 or "default1"
var2 = var2 or "default2"
var3 = var3 or "default3"

另請注意,Python有一個相當廣泛的“假”概念。 只有當var不能被賦值為零,False或任何被認為是“空”的對象(例如""[]{} ......)時,此構造才有效。 如果你真的希望它只在None上觸發,你必須寫更詳細的

var = var if var is not None else var_new

而且,而不是這樣做,我通常會尋找另一種方法來解決更大的問題。

最后,如果您可以像這樣構建代碼......

var1 = "default1"
var2 = "default2"
var3 = "default3"

# ... code here that may or may not set var1 through var3 ...

...那么你應該 ,因為它更短,更簡單,並且完全避免了None vs falsey問題。

不是很安全,但另一種選擇是:

var = locals().get('var', var_new)
try: var
except NameError: var = var_new

要么

var = locals().get('var', var_new)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM