2017-04-09 125 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.")