了解python 2.7 email.feedparser Feedparser __init__函数

时间:2012-08-23 21:45:52

标签: python python-2.7

(所以我正在努力学习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._parse设置为方法next

的返回值的self._parsegen()属性的值

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

有没有办法在解释器中查看这个,以便我可以逐步浏览脚本的每一行?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

next方法是一种生成python iteratorgenerator的下一个值的方法。考虑这个的最简单方法是重写一个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文档中的protocol for iterators。 (但基本上任何东西都可以是迭代器,如果它定义__iter__并生成一个定义__iter__next的迭代器。