Python - 下一个方法不能与生成器一起正常工作

Python - next method not working properly with generator

我在 python 中制作了一个 class 将代码流拆分为令牌并逐个令牌推进以与它们一起工作

import re

class Tokenizer:

    def __init__(self, input_file):
        self.in_file = input_file
        self.tokens = []
        self.current_token = None
        self.next_token = None
        self.line = 1

    def split_tokens(self):
        ''' Create a list with all the tokens of the input file '''
        self.tokens = re.findall("\w+|[{}()\[\].;,+\-*/&|<>=~\n]", self.in_file)

    def __iter__(self):
        for token in self.tokens:
            if token != '\n':
                yield token 
            else:
                self.line += 1

    def advance(self):
        self.current_token = self.next_token
        self.next_token = next(self.__iter__())

初始化后:

text = 'constructor SquareGame03 new()\n\
       {let square=square;\n\
       let direction=direction;\n\
       return square;\n\
       }'

t = Tokenizer(text)
t.split_tokens()
t.advance()

如果我打印令牌似乎有效

print(t.current_token, t.next_token)
None constructor

但是每隔一次调用 advance 方法都会给出这些结果:

t.advance()
print(t.current_token, t.next_token)
constructor constructor
t.advance()
print(t.current_token, t.next_token)
constructor constructor

所以它没有前进,我不明白为什么。

在这种情况下,.__iter__ 实现为 生成器函数 (而不是 生成器迭代器 ),其中 returns一个生成器迭代器.

每次调用 Tokenizer.advance 时,都会创建 一个新的 生成器迭代器 并由 .__iter__ 返回。相反,迭代器应在初始化阶段由 Tokenizer 对象存储,以供所有后续使用。

例如:

import re

class Tokenizer:

    def __init__(self, input_file):
        self.in_file = input_file
        self.tokens = []
        self.current_token = None
        self.next_token = None
        self.line = 1

    def split_tokens(self):
        ''' Create a list with all the tokens of the input file '''
        self.tokens = re.findall("\w+|[{}()\[\].;,+\-*/&|<>=~\n]", self.in_file)
        self.iterator = self.__iter__()

    def __iter__(self):
        for token in self.tokens:
            if token != '\n':
                yield token 
            else:
                self.line += 1

    def advance(self):
        self.current_token = self.next_token
        self.next_token = next(self.iterator)

另一个可以解释的最小例子:

def fib():
    a = 0
    b = 1
    while True:
        yield b
        a, b = b, a + b

# 1, 1, 2, ...
fibs = fib()
next(fibs)
next(fibs)
next(fibs)

# 1, 1, 1, ...
next(fib())
next(fib())
next(fib())

顺便说一句,我看不出混合使用 .__iter__ 魔术方法和单独的 .advance 方法的原因。它可能会引起一些混乱。