>>> False in [0]
True
>>> type(False) == type(0)
False
我偶然发现了这个原因:
对于我的单元测试,我为每个类型创建了有效和无效示例值的列表。 (我的意思是'我的类型',它们不是100%等于python类型) 所以我想迭代所有值的列表并期望它们在我的有效值中通过,另一方面,如果它们不是则失败。 现在这种方法效果不好:
>>> valid_values = [-1, 0, 1, 2, 3]
>>> invalid_values = [True, False, "foo"]
>>> for value in valid_values + invalid_values:
... if value in valid_values:
... print 'valid value:', value
...
valid value: -1
valid value: 0
valid value: 1
valid value: 2
valid value: 3
valid value: True
valid value: False
当然,我不同意最后两个“有效”值。
这是否意味着我必须遍历我的valid_values并比较类型?
答案 0 :(得分:15)
问题不在于缺少类型检查,而是因为在Python bool
中是int
的子类。试试这个:
>>> False == 0
True
>>> isinstance(False, int)
True
答案 1 :(得分:6)
根据documentation,__contains__
是通过==
迭代收集和测试元素来完成的。因此,实际问题是由False == 0
为True
。
答案 2 :(得分:4)
正如其他人所写的那样,“in”代码不会按照您的意愿执行。你还需要别的东西。
如果您真的想要进行类型检查(检查的类型完全相同),那么您可以在列表中包含该类型:
>>> valid_values = [(int, i) for i in [-1, 0, 1, 2, 3]]
>>> invalid_values = [True, False, "foo"]
>>> for value in [v[1] for v in valid_values] + invalid_values:
... if (type(value), value) in valid_values:
... print value, "is valid"
... else:
... print value, "is invalid"
...
-1 is valid
0 is valid
1 is valid
2 is valid
3 is valid
True is invalid
False is invalid
foo is invalid
>>>
处理子类型有点困难,取决于你想做什么。
答案 3 :(得分:3)
自True == 1
和False == 0
以来,很难区分这两者。
一种可能但很难看的方法(也不保证在所有Python实现中都能正常工作,但在CPython中应该没问题):
>>> for value in valid_values + invalid_values:
... if value in valid_values and not any(v is value for v in invalid_values):
... print ('valid value:', value)
...
valid value: -1
valid value: 0
valid value: 1
valid value: 2
valid value: 3