Python“in”不检查类型?

时间:2011-12-19 10:59:44

标签: python unit-testing types boolean identity

>>> 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并比较类型?

4 个答案:

答案 0 :(得分:15)

问题不在于缺少类型检查,而是因为在Python bool中是int的子类。试试这个:

>>> False == 0
True
>>> isinstance(False, int)
True

答案 1 :(得分:6)

根据documentation__contains__是通过==迭代收集和测试元素来完成的。因此,实际问题是由False == 0True

这一事实引起的

答案 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 == 1False == 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