【问题标题】:How make a callback class iterable instead of storing all callback parameters [duplicate]如何使回调类可迭代而不是存储所有回调参数[重复]
【发布时间】:2015-05-28 22:00:39
【问题描述】:

我有一个带有解析器的第 3 方库,它需要一个带有 new_token 方法的回调类。到目前为止,我的回调类和我的令牌处理如下所示:

class MySink(object):
    def __init__(self):
        self.tokens = []

    def new_token(self, token):
        self.tokens.append(token)

sink = MySink()
p = ThirdPartyParser(sink)
p.parse("my_data_file")

for t in sink.tokens:
    print t

令牌列表可能会变得很长(导致内存问题),所以我想将 MySink 变成一个可迭代的类,其中令牌不必存储在列表中,而是在fly 并且在处理令牌时停止解析。像这样的:

class MyIterableSink(object): # incomplete!
    def new_token(self, token):
        # TODO:
        # Store token for next iteration step
        # halt execution like with 'yield', wait for next iteration step

sink = MyIterableSink()
p = ThirdPartyParser(sink)
p.parse("my_data_file")

for t in sink:
    print t

如何修改MyIterableSink 类?这样的事情可能吗?我不能修改解析器类,只能修改回调类。我知道我必须实现__iter____next__ 方法并使用协程,其中令牌可能是使用send 方法发送的,但我不能完全理解它。任何代码示例都将不胜感激。

【问题讨论】:

  • @PadraicCunningham 不确定你的意思。对我来说,“容器”意味着所有令牌都存储在内部(就像现在的类一样)。我不想那样。相反,我希望一次只存储一个令牌。
  • 我编辑了示例代码以使其更清晰。令牌通过new_token 回调推送到类中。
  • 回调是异步的吗?
  • 不,回调是同步的。

标签: python callback iterator coroutine


【解决方案1】:

线

p.parse("my_data_file")

必须在循环中调用new_token。由于您无法更改第三方解析器的工作方式,因此您无法控制调用 new_token 的方式。使MySink 成为一个迭代器是行不通的,因为p.parse 没有迭代sink。因此,不要将 sink 设为迭代器,只需将标记处理为调用 new_token

class MySink(object): 
    def new_token(self, token):
        # process token
        print(token)

sink = MyIterableSink()
p = ThirdPartyParser(sink)
p.parse("my_data_file")

【讨论】:

    【解决方案2】:

    如果回调是异步的,你可以使用Queue:

    class MySink(object):
        def __init__(self):
             self.tokens = Queue()
    
        def new_token(self, token):
            self.tokens.put(token)
    
        def __iter__(self):
            token = self.tokens.get()
            while token is not None:
                yield token
                token = self.tokens.get()
    

    请注意,您必须为迭代器指定停止条件,例如超时或特殊令牌值(上例中的None)。

    编辑: 由于你的回调是同步的,unutbu 在他的answer 中说了这一切。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-01
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 2017-08-06
      • 1970-01-01
      相关资源
      最近更新 更多