2010-10-14 2313 views
59

我有一個Nonetypex,它通常是一個數字,但可能是None。我想把它除以數字,但Python提高了:如何將Nonetype轉換爲int或字符串?

TypeError: int() argument must be a string or a number, not 'NoneType' 

我該如何解決這個問題?

+5

假設沒有等於2771.但也許這不是你想要的。請提供更多信息。 – JoshD 2010-10-14 04:59:21

+0

不知何故,我得到一個Nonetype值,它應該是一個int值,但它現在是一個Nonetype對象,我需要分開另一個數字,然後錯誤出現了。 – user469652 2010-10-14 05:01:28

+0

'int(None)'拋出異常,因爲None不能轉換爲int。你的問題的答案是無法完成的。您可以替換0或2771之類的東西,或者粉紅色的大象,但是無論您替換什麼東西,您仍然無法將None轉換爲int。 – snapshoe 2010-10-14 05:17:02

回答

32

在一個評論,你說:

不知怎的,我得到了一個N​​onetype值,它應該是一個整數,但它現在是一個Nonetype對象

如果這是你的代碼,當你預期一個數字並且停止發生時,弄清楚你如何得到None

如果是別人的代碼,找出在這個時候它給出None的條件,並確定一個合理的值,使用的是,與通常的條件代碼:

result = could_return_none(x) 

if result is None: 
    result = DEFAULT_VALUE 

...甚至...

if x == THING_THAT_RESULTS_IN_NONE: 
    result = DEFAULT_VALUE 
else: 
    result = could_return_none(x) # But it won't return None, because we've restricted the domain. 

沒有理由自動使用0這裏 - 這取決於None「假」 -ness解決方案想你也需要這個。 DEFAULT_VALUE(如果它存在的話)完全取決於你的代碼的目的。

+4

+1的「正確」解決方案。如果你的窗口經常被神祕地破壞,找出爲什麼(並且抓住負責的破壞者)而不是阻塞窗口;) – delnan 2010-10-14 07:59:23

+3

這對於從redis字典檢索密鑰的情況是沒有用的,例如,因爲丟失的密鑰將會沒有。如果你想總結他們而不管他們的存在(這是完全可以接受的行爲),你可能需要將None轉換爲0(參見kindall answer) – spider 2013-11-28 17:02:11

+1

@spider - 這仍然意味着它高度依賴於情況,並且「確定一個合理的價值「仍然適用。 – detly 2013-11-28 21:08:45

10

只有當您嘗試通過int()None(這是唯一的NoneType值,據我所知)時纔會出現TypeError。我想說,你的真正目標不應該是將NoneType轉換爲intstr,而是要找出你在哪裏/爲什麼得到None而不是按照預期的數字,並且修正它或正確處理None

+0

傳遞int( )'一個複雜的數字,比如'int(1 + 2j)',也會引發一個'TypeError',雖然承認這可能不太可能。無論如何,我認爲你的話毫無疑問是一個好的建議。 – martineau 2017-03-08 01:36:40

1

您應該檢查以確保值是試圖對其執行任何計算之前無:

my_value = None 
if my_value is not None: 
    print int(my_value)/2 

注:my_value是故意設置爲無證明代碼工作和該檢查正在執行中。

+1

你應該使用身份比較('is [not] None') – shylent 2010-10-14 05:37:55

+0

-4你應該鼓勵OP找出他真正的問題,而不是避免它。 @shylent說。您無條件地將'my_value'設置爲None;爲什麼?當'my_value'(如果不是None)「通常是一個數字」時,你不會質疑爲什麼OP認爲他需要'int(my_value)'。 – 2010-10-14 06:34:23

+1

我將my_value設置爲None作爲概念驗證,以顯示我的代碼不會失敗。我沒有質疑OP,因爲有很多原因可能導致值不總是數字,並且在執行計算之前檢查它是否是一個好主意。回答OP的問題沒有什麼不對,我不必爲他們做所有的功課。 – Soviut 2010-10-14 07:37:52

213
int(value or 0) 

這將在的情況下使用0時提供了Python認爲False,如無,0,[]「」等。由於0是False,應該只使用0作爲任意值替代值(否則你會發現你的0變成了這個值)。

int(0 if value is None else value) 

這僅替換None爲0。由於我們正在爲None專門測試,你可以使用一些其他值作爲替代。

+47

user469652您應該考慮將此作爲接受的答案。它實際上是有益的,而不是居高臨下 – galarant 2013-01-22 03:04:12

+0

我不知道這是否解決了用戶面臨的問題即。使用nonetype來執行計算...我目前正在通過一個rest api,這是返回一個nonetype包含數值拉動數據。如果我將它設置爲0或保留它,因爲它是我不能做任何事情 – br3w5 2013-12-31 17:13:07

+1

所以我必須在我的代碼中找到錯誤 – br3w5 2013-12-31 17:22:19

1

如果忘記從函數返回值,則會發生這種情況:然後返回None。查看分配給該變量的所有地方,並查看其中的一個是否是函數調用,其中函數缺少返回語句。

+1

...或者函數有一個或多個返回語句,它們只是簡單的'return'而不是'return some_expression'。 – 2010-10-14 06:39:41

+0

...或者該函數包含一個或多個'return None'語句 – 2010-10-14 09:50:41

10

一個共同的「Python化」的方式來處理這種情況被稱爲EAFP爲「它更容易請求原諒比許可」。這通常意味着編寫假定一切都很好的代碼,但隨後將其封裝爲try..except塊,以防萬一不能處理。

這裏是適用於您的問題,編碼風格:

try: 
    my_value = int(my_value) 
except TypeError: 
    my_value = 0 # or whatever you want to do 

answer = my_value/divisor 

或者也許更簡單和速度稍快:

try: 
    answer = my_value/divisor 
except TypeError: 
    answer = 0 

逆與更傳統的方法被稱爲LBYL矗立爲「看你跳躍」是什麼@Soviut和其他一些人建議。有關此主題的其他內容,請參閱我的answer以及本網站其他地方的問題Determine whether a key is present in a dictionary的相關評論。

一個潛在的問題與EAFP是,它可以隱瞞事實的東西是你的代碼錯誤或第三方模塊的其他部分你使用,特別是當異常頻繁發生(因此不是活得根本沒有什麼特殊的情況)。

1

我有使用Python電子郵件功能相同的問題。 下面是我試圖將電子郵件主題檢索到一個變量的代碼。這適用於大多數電子郵件和變量填充。如果您收到來自雅虎等的電子郵件,並且發件人沒有填寫主題行,雅虎不會在電子郵件中創建主題行,並且您會從該函數返回一個NoneType。 Martineau和Soviut一樣提供了正確的答案。從編程的角度來看,IMO Soviut的答案更加簡潔;不一定來自Python。 下面是一些代碼,以顯示技術:

import sys, email, email.Utils 

afile = open(sys.argv[1], 'r')  
m = email.message_from_file(afile)  
subject = m["subject"] 

# Soviut's Concise test for unset variable. 

if subject is None:  
    subject = "[NO SUBJECT]" 

# Alternative way to test for No Subject created in email (Thanks for NoneThing Yahoo!) 

try:  
    if len(subject) == 0:  
     subject = "[NO SUBJECT]" 

except TypeError:  
    subject = "[NO SUBJECT]" 

print subject 

afile.close() 
2

我已經成功地使用INT(x或0)對於這種類型的錯誤,只要無應等同於0中的邏輯。 請注意,在測試x返回False的其他情況下,這也將解析爲0。例如空列表,集合,字典或零長度字符串。 對不起,Kindall已經給出了這個答案。