为什么在此iter调用中必须使用哨兵?

时间:2020-10-06 10:27:34

标签: python

将可迭代对象转换为迭代器时,我不习惯看到哨兵。这是我正在分析的代码:

import re
NAME = r'(?P<NAME>[a-zA-Z_][a-zA-Z_0-9]*)'
NUM  = r'(?P<NUM>\d+)'
PLUS = r'(?P<PLUS>\+)'
TIMES = r'(?P<TIMES>\*)'
EQ    = r'(?P<EQ>=)'
WS    = r'(?P<WS>\s+)'
master_pat = re.compile('|'.join([NAME, NUM, PLUS, TIMES, EQ, WS]))

from collections import namedtuple
Token = namedtuple('Token', ['type','value'])

def generate_tokens(pat, text):
    import pdb;pdb.set_trace()
    scanner = pat.scanner(text)
    for m in iter(scanner.match,None):
        yield Token(m.lastgroup, m.group())
# Example use
for tok in generate_tokens(master_pat, 'foo = 42'):
    print(tok)

为什么定点是强制性的? 我没想到会看到此错误:

(Pdb) it2=iter(scanner.match)     
*** TypeError: 'builtin_function_or_method' object is not iterable

1 个答案:

答案 0 :(得分:2)

iter内置函数状态的帮助:

从对象获取迭代器。在第一种形式中,参数必须 提供自己的迭代器,或者是一个序列。 在第二种形式中,可调用对象被调用,直到返回哨兵。

在第一种形式中,传递给iter的对象已经可以迭代,因此iter可以创建一个迭代器并进行迭代,直到迭代器耗尽为止。

在第二种形式(如问题所示)中,传递给iter的第一个参数是可调用的。 iter需要哨兵参数来确定何时停止调用可调用对象。

第二种形式等效于:

def iter(some_func, sentinel):
    while True:
        retval = some_func()
        if retval == sentinel:
            break
        yield retval