为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

呼啦一阵风 2023-02-07 13:52:48
我在 python 中创建了一个类,它将代码流拆分为令牌并逐个令牌推进令牌以与它们一起使用import reclass 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 constructort.advance()print(t.current_token, t.next_token)constructor constructor所以它没有进步,我不明白为什么。
查看完整描述

1 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

在这种情况下,.__iter__它被实现为生成器函数(而不是生成器迭代器),它返回一个生成器迭代器。


每次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方法的原因。它可能会引起一些混乱。


查看完整回答
反对 回复 2023-02-07
  • 1 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号