1

(所以我正在尝试学习python。我认为阅读比我更好的人的代码会很好。我决定通读电子邮件模块......)

init模块中 Feedparser 类的函数email.feedparser定义为:

def __init__(self, _factory=message.Message):
    """_factory is called with no arguments to create a new message obj"""
    self._factory = _factory
    self._input = BufferedSubFile()
    self._msgstack = []
    self._parse = self._parsegen().next
    self._cur = None
    self._last = None
    self._headersonly = False

我遇到的问题是:

self._parse = self._parsegen().next

我认为应该意味着'将属性设置为方法返回值的属性self._parsenextself._parsegen()

据我所知,self._parsgen()在调用期间__init__()将首先调用self._new_message()它将设置/添加值到self._cur,self._lastself._msgstack. 然后它将一个空列表对象分配给局部变量headers,然后开始迭代该self._input对象。我认为 for 的第一个值line将是一个NeedMoreData对象。由于NeedMoreData该类只是扩展对象,因此它应该没有名为的属性或方法next。那么是否next只是指回迭代器(self._input)?

有什么办法可以在解释器中查看这个,以便我可以单步执行脚本的每一行?

4

2 回答 2

4

那么是否next只是指回迭代器(self._input)?

next确实指的是生成器。由于该_parsegen()方法使用yield,它返回一个生成器对象。考虑以下简单示例(来自 IPython):

In [1]: def a():
   ...:     yield 1
   ...:     yield 2
   ...:     

In [2]: a()
Out[2]: <generator object a at 0x1a56550>

In [3]: a().next
Out[3]: <method-wrapper 'next' of generator object at 0x1a567d0>

In [4]: a().next()
Out[4]: 1

所以,是的,你基本上是对的。它将下降到迭代器,并引用从它返回下一个值的方法。

有什么办法可以在解释器中查看这个,以便我可以单步执行脚本的每一行?

您可以为此使用pdb

于 2012-08-23T22:29:41.343 回答
2

next方法是一种生成 pythoniteratorgenerator. 考虑这个问题的最简单方法是重写一个 for 循环。

你有一个非常简单的语法来循环列表:

for element in list:
    print element 

element这将在每次迭代中产生一个。但实际上,Python 正在做类似这样的事情:

iterator = iter(list)
while True:
    element = iterator.next()
    # do something with element (e.g. print it)
    print element

当迭代器耗尽(没有更多项)时,它会引发StopIteration异常,这就是for循环和其他使用迭代器的方法知道何时停止的方式。(所以前面的代码片段真的应该被包装在一个try/except块中,但我认为没有它会更清楚阅读)。

您可以在 Python 文档中阅读有关迭代器的协议。(但基本上任何东西都可以是迭代器,如果它定义__iter__并产生一个定义 and 的迭代__iter__next

于 2012-08-23T22:30:04.843 回答