Python"in"不检查类型?

Mar*_*cka 14 python types unit-testing identity boolean

>>> False in [0]
True
>>> type(False) == type(0)
False
Run Code Online (Sandbox Code Playgroud)

我偶然发现这个原因:

对于我的单元测试,我为每个类型创建了有效和无效示例值的列表.(使用'my types'我的意思是,它们不是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
Run Code Online (Sandbox Code Playgroud)

当然,我不同意最后两个"有效"的价值观.

这是否意味着我真的必须遍历我的valid_values并比较类型?

Con*_*ius 15

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

>>> False == 0
True
>>> isinstance(False, int)
True
Run Code Online (Sandbox Code Playgroud)

  • 如果序列中的一个项与所请求的对象"相等",则`in`返回true.所以你的问题不是`in`运算符,而是`==`运算符. (6认同)
  • 刚检查[PEP 285,添加bool类型(在*规格*下)](http://www.python.org/dev/peps/pep-0285/)和'True + 1 == 2`将起作用向后兼容性. (3认同)

nd.*_*nd. 6

根据文档,__contains__通过迭代遍历集合和测试元素来完成==.因此,实际的问题是由以下事实造成的,即False == 0True.


And*_*lke 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
>>> 
Run Code Online (Sandbox Code Playgroud)

处理子类型有点困难,这取决于您想要做什么。