Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.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迭代器协议在迭代器返回值中?_Python_Iterator_Iterable - Fatal编程技术网

Python迭代器协议在迭代器返回值中?

Python迭代器协议在迭代器返回值中?,python,iterator,iterable,Python,Iterator,Iterable,因此,我最近在python类中了解了迭代器协议,并且我被告知\uuuuiter\uuuuuuuuuuuuuuuuuuuuuuself)方法应该始终返回一个新的迭代器,而不是self。在流畅的Python书中,它谈到在迭代器中返回self,因此我不确定为什么我的导师告诉我不能使用self作为返回值 这是我们在考试中遇到的一个例子,我因为使用self而不是FileName迭代器而丢了分数 class FileNamesIterator: """ Iter

因此,我最近在python类中了解了迭代器协议,并且我被告知
\uuuuiter\uuuuuuuuuuuuuuuuuuuuuuself)
方法应该始终返回一个新的迭代器,而不是
self
。在流畅的Python书中,它谈到在迭代器中返回
self
,因此我不确定为什么我的导师告诉我不能使用self作为返回值

这是我们在考试中遇到的一个例子,我因为使用self而不是FileName迭代器而丢了分数

class FileNamesIterator:
    """
    Iterator that iterates over all the file names in the
    FileNamesIterable.
    """

    def __init__(self, filename_iterable: FileNamesIterable):
        self.filename_iterable = filename_iterable
        self.curr_index = 0

    def __next__(self) -> str:
        file_list = self.filename_iterable.file_list
        if self.curr_index == len(file_list):
            raise StopIteration()

        next_file_name = file_list[self.curr_index]
        self.curr_index += 1

        if ".png" in next_file_name:
            next_file_name = f"{next_file_name} - Portable Network Graphics " \
                             f"File"
        elif ".gif" in next_file_name:
            next_file_name = f"{next_file_name} - Graphics Interchange " \
                             f"Format File"

        return next_file_name

    def __iter__(self) -> FileNamesIterator:
        return self


class FileNamesIterable:
    def __init__(self, file_list: list):
        self.file_list = file_list

    def __iter__(self) -> FileNamesIterator:
        return FileNamesIterator(self)

要在容器类中实现迭代器协议,需要向其添加一个
\uuuu iter\uuu
方法。这允许使用
for
循环对类实例进行迭代,因为它在类实例上调用
iter()
,以获取迭代器对象(从
实例中)。然后从返回的对象(迭代器)调用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu(提升
StopIteration
,而不是返回另一个数据值)。这就是迭代器类的
\uuuIter\uuuuuuuuuuuuuu
方法应使用
\uuuuuuuuuuuuu
方法返回对象的原因

如果实现协议的类本身可以有
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

class MyIterator:
    def __init__(self, data):
        self._data = data
        self._index = 0

    def __next__(self):
        if self._index == len(self._data):
            raise StopIteration
        self._index += 1
        return self._data[self._index-1]

    def __iter__(self):
        return self
如果将迭代器类与iterable对象分开,则必须返回新的迭代器对象,而不是
self
(也不是迭代器类名):

输出:

Using a single class:
<__main__.MyIterator object at 0x7f65a23b6fd0>
1
2
3

Separating the iterator class from the container class:
<__main__.Iterator object at 0x7f65a23b6ca0>
1
2
3
使用单个类:
1.
2.
3.
将迭代器类与容器类分离:
1.
2.
3.
Using a single class:
<__main__.MyIterator object at 0x7f65a23b6fd0>
1
2
3

Separating the iterator class from the container class:
<__main__.Iterator object at 0x7f65a23b6ca0>
1
2
3