2016-01-15 96 views
2

有上Idiomatic Python - checking for zero一個問題,但這個問題是考慮也是檢查的條件範圍內的變量的類型。申報條件 - 蟒蛇

鑑於0 if not variable else variable樣式聲明,它會讓nully對象漏網之魚,例如

>>> x, y = None, [] 
>>> 0 if not(x and y) else x/y 
0 
>>> x, y = None, 0 
>>> 0 if not(x and y) else x/y 
0 
>>> x, y = 0, 1 
>>> 0 if not(x and y) else x/y 
0 
>>> x, y = 2, "" 
>>> 0 if not(x and y) else x/y 
0 
>>> x, y = 2, 1 
>>> 0 if not(x and y) else x/y 
2 

但是,如果我明確檢查變量的值爲零,這將是稍微好一些,因爲它時,這兩種類型是不同的,或者無法比擬的零值類型,例如,會引發錯誤:

>>> x, y = 2, "" 
>>> 0 if (x&y) == 0 else x/y 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for |: 'int' and 'str' 
>>> x,y = "","" 
>>> 0 if (x&y) == 0 else x/y 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for |: 'str' and 'str' 
>>> x,y = [],[] 
>>> 0 if (x&y) == 0 else x/y 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for |: 'list' and 'list' 

限定條件來檢查數值時所以通常,是一樣的東西的0 if (x|y) == 0 else x/y代碼更Python /比較合適?

但因爲它讓我們通過布爾型滑它也是有問題的,會導致像ZeroDivisionErrorValueError一些相當令人心煩的事發生,例如:

>>> x,y = True, True 
>>> 0 if (x&y) == 0 else x/y 
1 
>>> x,y = True, False 
>>> 0 if (x&y) == 0 else x/y 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ZeroDivisionError: integer division or modulo by zero 
>>> x,y = False, True 
>>> 0 if (x&y) == 0 else x/y 
0 
>>> x,y = False, True 
>>> 0 if (x&y) == 0 else math.log(x/y) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: math domain error 

而且,這會導致問題,當變量類型是數字但有所不同:

>>> x, y = 1, 3. 
>>> 0 if (x|y) == 0 else math.log(x/y) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for |: 'int' and 'float' 

,也是事實,該_or運營商不能採取浮動,它的怪異:

>>> x, y = 1., 3. 
>>> 0 if (x&y) == 0 and type(x) == type(y) == float else math.log(x/y) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for |: 'float' and 'float' 
>>> x, y = 1., 3. 
>>> 0 if (x&y) == 0. and type(x) == type(y) == float else math.log(x/y) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for |: 'float' and 'float' 
>>> x, y = 1, 3 
>>> 0 if (x&y) == 0 and type(x) == type(y) == float else math.log(x/y) 
-1.0986122886681098 

所以,問題是:

  • 什麼是檢查的零值的多個變量的Python的方式?
  • 此外,它不喜歡布爾型滑和提高一個錯誤是很重要的,而不是讓它返回零的,這可怎麼辦呢?
  • 如何解決TypeError: unsupported operand type(s) for |: 'float' and 'float'檢查(x|y) == 0 x和y爲浮點類型?
+4

如果你有數值運算依賴於準確類型兩個操作數的,明顯的(因此Python的)解決方案是明確地檢查類型的兩個操作數或處理預期異常。 –

+1

顯式檢查怎麼樣:「在(x,y)中爲0」? –

+0

@ A.Haaji這將失敗的布爾:在(真,假)=>'0 TRUE' –

回答

4

隨着PEP 20的‘簡單比複雜好’這一點,我會聲稱,如果要檢查的值是否比布爾值以外的數值類型(記:布爾數值類型在Python和1/True是有效的),最Python的方式做到這一點是要做到這些,明確的,沒有任何位操作或依賴隱式檢查。

import numbers 

if not isinstance(y, numbers.Number) or type(y) is bool: 
    raise TypeError("y must be a number") 
return x/y if y else 0 
+0

酷!不知道'數字'有一些很酷的元素和課程! – alvas