(所以我正在努力学习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._cur
,self._last
的值,和self._msgstack
。然后,它会将空列表对象分配给局部变量headers
,然后开始迭代self._input
对象。我认为line
的第一个值是NeedMoreData
个对象。由于NeedMoreData
类只是扩展对象,因此它应该没有名为next
的属性或方法。那么next
只是引用回迭代器(self._input
)?
有没有办法在解释器中查看这个,以便我可以逐步浏览脚本的每一行?
答案 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 iterator
或generator
的下一个值的方法。考虑这个的最简单方法是重写一个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
的迭代器。