2017-04-09 99 views
0

我想做出一些錯誤捕獲的代碼。無論函數的輸入是什麼,它總是會執行第一個if語句的else塊。它爲什麼這樣做?如果語句執行Else,即使If似乎是真的?

這是錯誤醒目代碼:

def rgbtohex(r=0, g=0, b=0): 
    '''Converts RGB values to hecadeximal values. Supports 3 integers, one list, or one tuple.''' 
    if type(r) == 'int' and type(g) == 'int' and type(b) == 'int': 
     if r > 255 or g > 255 or b > 255: 
      raise ValueError('one or more arguments are above 255.') 
    elif type(r) == 'list' or type(r) == 'tuple': 
     if r[0] > 255 or r[1] > 255 or r[2] > 255: 
      raise ValueError('one or more index values are above 255.') 
     if g == 0 and b == 0: 
      r = r[0] 
      g = r[1] 
      b = r[2] 
     else: 
      raise TypeError('rgb values not integers, single list, or single tuple.') 
     return 
    else: 
     raise TypeError('one or more arguments are not integers.') 
    ... 
+0

順便說一句,你可能要檢查整數值不小於0或者.... :) –

回答

3

在Python,整數型是int,不是字符串"int"

刪除引號。

同上tuplelist

這是一個很容易犯的錯誤,因爲其他語言如JavaScript和Lua使用字符串來指示類型。但是在Python中(如Ruby中),類型是實際的對象,並由標識符引用。

肥皂盒

要考慮的事情:我看到你正試圖使用​​戶可以通過其中三個整數,或元組,或列表的功能。您正在試圖讓你的來電者在這裏有一定的靈活性,這是難能可貴的,但你已經結束了的東西,

  1. 做的論據類型檢查,這是不是超級Python的,和
  2. 使用參數名爲r的列表或元組!

第二部分意味着有人可以調用

rgbtohex(R = [21128123])

這是一種奇怪的。

我會做什麼是定義你的功能僅作爲

def rgbtohex(r = 0, g = 0, b = 0): 
    ... 

如果你的用戶列表或元組,他們會知道解包並調用這樣的:

my_color = [21,128,123] 
rgbtohex(*myColor) 

這裏是如何我應該這樣做:

def rgbtohex(r=0, g=0, b=0): 
    if not all(c in range(256) for c in (r, g, b)): 
     raise ValueError('Components must be in range 0...255') 
    return '#{:02x}{:02x}{:02x}'.format(r, g, b) 

assert(rgbtohex() == '#000000') 
assert(rgbtohex(9, 20, 255) == '#0914ff') 
assert(rgbtohex(9, b=20, g=192) == '#09c014') 
assert(rgbtohex(*[11, 0, 0]) == '#0b0000') 
// Negative tests left as an exercise for the reader ;-) 
+0

,你有什麼建議我重新命名參數' r'到? –

+0

這個參數沒有好的名字,因爲你使用它作爲三個整數的第一個,並且作爲唯一的元組或數組。這種雙重使用參數是一個真正的紅旗,或「代碼味道」,真正的TBH應該避免。我認爲這很好,你想爲那些調用你的函數的人提供一些靈活性,但是Python是一種現代語言,它已經提供了很酷且靈活的特性。恕我直言,你應該採取我的答案建議,並完全避免類型檢查。僅支持r,g,b的3參數版本。如果他們有一個列表,你的用戶將使用'*'。 –

2

即使如果是真的?

從來沒有承擔這一點。代碼不是謊言。當type(r)實際上是一個int(不含引號)

type(r) == 'int'永遠不會爲真

試試吧print(type(r) == 'int')


不要串你的類型。

例如,雖然isinstance(r, int)看起來更好

至於檢查列表,集合,元組等

In Python, how do I determine if an object is iterable?

+0

非常感謝您的回答。我執行'print(type(1))',返回的結果是''。然後我假設整數的輸入是'string'格式,因爲我不知道'type'是一個實際的類型(如果這是有意義的)。簡單的初學者我的錯誤。 –

0

你可以使用isinstance()方法,因爲比較的intstr將永遠是False

所以你可以改變你的狀況

if type(r) == 'int' and type(g) == 'int' and type(b) == 'int': 
    # process 

到:

if isinstance(r, int) and isinstance(g, int) and isinstance(b, int): 
    # process 

做的,相同的其他條件。

0

type()返回的值的類型是'type'類型的。要檢查是否x是一個整數,使用此代碼:

if type(x) == type(5): 
    print("X is an integer.")