2009-10-20 41 views
270

Possible Duplicate:
Easy way to check that variable is defined in python?
How do I check if a variable exists in Python?確定是否變量在Python

定義你怎麼知道一個變量是否已經被設置爲在運行時代碼一個特別的地方?這並不總是顯而易見的,因爲(1)變量可以被有條件地設置,並且(2)變量可以被有條件地刪除。我正在尋找Perl中的defined()或PHP中的isset()或Ruby中的defined?

if condition: 
    a = 42 

# is "a" defined here? 

if other_condition: 
    del a 

# is "a" defined here? 
+9

Duplicates:http://stackoverflow.com/questions/843277/python-checking-variable-existing,http://stackoverflow.com/questions/750298/easy-way-to-check-that-variable-is -python -defined, – carl 2009-10-20 06:50:58

+54

請請,請不要「有條件地」設置一個變量。這只是可怕的,可怕的設計。始終,始終提供所有邏輯路徑。請不要繼續這樣做。 – 2009-10-20 10:35:38

+1

+1 S.Lott anwser。事實上,有辦法做到這一點並不意味着你應該在一個新的項目中使用它。 – 2010-03-31 13:48:06

回答

451
try: 
    thevariable 
except NameError: 
    print "well, it WASN'T defined after all!" 
else: 
    print "sure, it was defined." 
+66

@Aaron:當你不知道變量是否定義時,有很多情況。您可以重構代碼以避免在很多情況下出現這種情況,但不是所有情況。亞歷克斯的解決方案是正確的,並且由於某些原因,當重現不可能時它是最好的。問題中沒有太多的信息,所以我相信只有人問他可以選擇最好的方式來處理他的案件。 – 2009-10-20 07:58:29

+124

@Aaron,「should」是一個4個字母的單詞 - 例如沒有哪個車手「應該」超過速度限制,但這並不意味着你不會對那些仍在使用的人採取一切正確和必要的預防措施。保留脆弱的,遺留的代碼,其設計有些破碎,而且是從別人身上繼承下來的,這是一個生活中的事實,那些只能從頭開始思考大爆炸而不是謹慎和不斷增加的重寫需要重讀Joel的9年-old essay http://www.joelonsoftware.com/articles/fog0000000069.html。 – 2009-10-20 14:51:37

+10

@ S.Lott人們用它來保持向後兼容性。在Python 3.1源代碼中搜索NameError。有很多例子使用「try:var_name,除了NameError:something_else」。以下是使用它的幾個地方:CSV(http://svn.python.org/projects/python/trunk/Lib/csv.py)庫和ElementTree庫(http://svn.python。組織/項目/蟒蛇/主幹/庫/ XML/etree/ElementTree.py)。 – sc45 2009-10-20 14:54:50

11
try: 
    a # does a exist in the current namespace 
except NameError: 
    a = 10 # nope 
+5

例外應僅用於特殊情況。參見[this discussion](http://stackoverflow.com/q/77127/1593077) – einpoklum 2015-04-10 22:17:38

+10

@einpoklum對於大多數語言來說都是如此,但是在Python中,例外情況會更頻繁地使用,請參閱參考資料。 http://stackoverflow.com/questions/3086806 – sdcvvc 2015-04-27 20:32:52

+1

嗯,很奇怪,但真的,顯然。我仍然認爲這不是一個好主意(TM),但是,不能與社區風俗爭論。 – einpoklum 2015-04-28 19:43:16

235

'a' in vars() or 'a' in globals()

如果你想成爲迂腐

,您可以檢查內建太
'a' in vars(__builtin__)

+17

這應該是我相信的答案。見http://stackoverflow.com/questions/843277/python-checking-variable-existing – 0atman 2010-11-04 13:41:49

+1

這是一個非常習慣的答案。這裏有一個強大的用例來表示地圖;例如,在{「prop0」中:「if」prop2「:無,」prop1「:無}:' – robert 2016-02-19 18:46:36

+0

該答案也適用於檢測變量以外的成員,如函數,類和模塊。 – aaaantoine 2017-09-15 15:22:44

91

我覺得這是更好地避免這種情況。這是更清潔和更清晰的寫:

a = None 
if condition: 
    a = 42 
+6

如果你喜歡這樣做,你應該使初始值獨一無二,這樣你就可以將'a'設置爲'None'。 'UNDEFINED = object(); a = UNDEFINED'然後你可以用'a不是UNDEFINED'測試 – 2009-10-20 07:03:00

+11

這是None的常見用法。這實際上就是None的語義 - 它不是什麼,nada,zip。它存在,但「沒有價值」。如果None可以出現在賦值等中,那麼使用non-None值非常有用,但這並不常見,因此避免使用None應該是標準做法。例如,在這個問題中,a只會是42或者不確定。將未定義更改爲值爲無會導致信息丟失。 – 2010-02-03 05:27:07

+3

這是方式,不知道爲什麼人們認爲使用LONG和DIRTY try/except構造來完成這個過程。此外,在不想將默認值硬編碼到參數列表(僅將默認值定義爲類成員)的類成員函數中使用關鍵字args時,這非常有用。 – FizxMike 2014-02-14 17:13:44

4

對於這種特殊的情況下,最好做a = None而不是del a。這會將引用計數遞減到對象a被分配給(如果有的話),並且在未定義a時不會失敗。請注意,del語句不直接調用對象的析構函數,而是將其從變量中解除綁定。對象的析構函數在引用計數變爲零時被調用。

4

一種可能的情況下,這可能需要:

如果使用finally塊關閉連接,但在try塊,程序與sys.exit()退出定義連接之前。在這種情況下,將調用finally塊,並且連接關閉語句將失敗,因爲沒有創建連接。

-2

如果想要趕上試圖訪問的對象裏面沒有定義的變量,有這樣做的一個非常簡單的方法:

class Whatever(object): 
    def __getattr__(self, key): 
    return None 

這裏,蟒首先嚐試找對象中的屬性或對象樹,並且只有在失敗時調用__getattr__(self, key)函數。 這意味着,如果__getattr__被調用,我們可以簡單地返回None

+0

-1'__getattr__'是查字典之前調用。 – quantum 2012-10-20 01:16:21

+0

@量子不,這不是,但'__getattribute__'是查字典之前調用。 – 2016-04-24 02:17:05

相關問題