Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 是“…”;。。。“对象不可编辑”;“的误导性错误”;x在y中;?_Python_Language Lawyer - Fatal编程技术网

Python 是“…”;。。。“对象不可编辑”;“的误导性错误”;x在y中;?

Python 是“…”;。。。“对象不可编辑”;“的误导性错误”;x在y中;?,python,language-lawyer,Python,Language Lawyer,考虑以下两类: class Foo0(object): pass class Foo1(object): def __contains__(self, _): return False 这两种方法都不可移植,可以通过在Foo1()中为i尝试:pass: Traceback (most recent call last): File "stuff.py", l

考虑以下两类:

class Foo0(object):                                                 
    pass

class Foo1(object):
    def __contains__(self, _):
        return False
这两种方法都不可移植,可以通过在Foo1()中为i尝试
:pass

Traceback (most recent call last):
   File "stuff.py", line 11, in <module>
    for i in Foo1(): pass
TypeError: 'Foo1' object is not iterable

我发现这个错误有误导性。问题的关键不是
Foo0
不可编辑-毕竟
Foo1
也不可编辑,所以这不是内在原因。此外,正如@niemmi和@tobias_k在下面正确指出的那样,如果一个类不支持
\uuuuu包含
\uuuuu iter\uuuu
将用作回退,这是导致此错误的直接原因。然而,这会让事情变得更糟,因为用户可能会试图通过实现
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
来解决此错误,这是一种非常低


那么,为什么选择这个作为错误呢?

如果对象没有方法,Python会自动尝试对其进行迭代,以查看是否可以找到元素。因为
Foo0
不是一个iterable,所以您将看到错误

更新:更详细地解释这一点:

对于定义contains()方法的用户定义类,y中的x为真当且仅当y.contains(x)为真时

对于不定义包含()但定义iter()的用户定义类,如果在y上迭代时生成某个值z且x==z,则y中的x为真。如果在迭代过程中引发异常,就好像在中引发了该异常一样

最后,尝试旧式的迭代协议:如果一个类定义了getitem(),当且仅当存在一个非负整数索引i,使得x==y[i],并且所有较低的整数索引都不会引发索引器异常时,y中的x为真。(如果引发任何其他异常,则与引发该异常一样)


谢谢,尼米,这也是我的理解。然而,它解释了这是如何发生的,而不是如果这是语言设计者想要的理由。回答得不错。错误消息应该可以解释根本原因,而不是回退失败的原因。
Traceback (most recent call last):
  File "stuff.py", line 9, in <module>
    3 in Foo0()
TypeError: argument of type 'Foo0' is not iterable