当前位置: 代码迷 >> python >> 为什么'in'关键字声称它需要一个可迭代对象?
  详细解决方案

为什么'in'关键字声称它需要一个可迭代对象?

热度:60   发布时间:2023-06-16 10:10:09.0
>>> non_iterable = 1
>>> 5 in non_iterable
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'int' object is not iterable

>>> class also_non_iterable:
...     def __contains__(self,thing):
...         return True

>>> 5 in also_non_iterable()
True
>>> isinstance(also_non_iterable(), Iterable)
False

是否有一个原因in关键字号称要一个迭代对象时,它真正想要的是实现一个对象__contains__

它声称需要一个可迭代的,因为如果对象的类没有实现__contains__ ,那么in尝试迭代对象并检查值是否等于它的值。

举例说明 -

>>> class C:
...     def __iter__(self):
...         return iter([1,2,3,4])
>>>
>>> c = C()
>>> 2 in c
True
>>> 5 in c
False

这在有解释

为它定义了用户定义的类__contains__()方法, x in y ,如果仅当且为真y.__contains__(x)是真实的。

对于没有定义__contains__()但是定义__iter__()用户定义的类,如果在迭代y产生一些带有x == zz ,则x in y为真。 如果在迭代期间引发异常,则就好像在异常中引发异常一样。

是否有一个原因in关键字号称要一个迭代对象时,它真正想要的是实现一个对象__contains__

x in thing for x in thing中的for x in thing是非常密切相关的。 几乎所有支持x in thing遵循规则,即当for循环的thing将找到一个等于x的元素时x in thing中的x in thing为真。 特别是,如果一个对象支持迭代但不__contains__ ,Python将使用迭代作为后备in测试。

错误消息可能会说它需要__contains__ ,但这与当前消息一样错误,因为__contains__不是绝对必要的。 它可以说它需要一个容器,但它不能立即清楚什么算作一个容器。 例如,http://stardict.sourceforge.net/Dictionaries.php下载支持in ,但美其名曰容器是值得商榷的。 当前消息表示它需要可迭代,与其他选项一样准确。 它的优点是,在实践中,“是迭代”是一个更好的检查比“是它的容器”或“它支持__contains__ ”确定实际的对象是否支持in

in有两种不同的用途:

  • 测试容器是否有值(例如,左参数实现__contains__
  • 遍历一个序列(例如,右参数是Iterable
  相关解决方案