2012-08-23 72 views
1

(所以我试图学习python,我认为阅读代码会比我更好,我决定阅读电子邮件模块...)了解python 2.7 email.feedparser Feedparser __init__函数

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

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._cur,self._lastself._msgstack。然后它会将一个空列表对象分配给本地变量headers,然后开始迭代self._input对象。我认为line的第一个值将是一个NeedMoreData对象。由于NeedMoreData类只是扩展对象,因此它不应具有名为next的属性或方法。那么next只是指向迭代器(self._input)?

有什么办法可以在解释器中看看这个,这样我就可以遍历脚本的每一行了?

+2

您可以在任何代码中设置调试器断点(你自己的,第三方的模块或标准库的Python部分)像这样: 'import pdb; pdb.set_trace()' 这会在您碰到那行代码时立即将您引入内置的调试器pdb中,然后您可以使用'n'执行下一个(跳过),进入下一行的评估(例如函数调用),'w'显示调用堆栈,''显示围绕你所在行的代码上下文,当然也可以做任何你能在常规口译中做的事情。 –

回答

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了点。

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迭代器。