在 AsyncGenerator/AsyncIterator 中检查 __contains__

问题描述 投票:0回答:1

在同步 python 中,我可以使用

in
运算符检查迭代器是否包含值:

def my_iterator():
    print('A')
    yield 1
    print('B')
    yield 2
    print('C')
    yield 3 


print(2 in my_iterator())
# A
# B
# True

但是,如果我尝试使用

AsyncGenerator
执行此操作,则没有真正的方法可以使用
in
运算符执行此操作。 我可以让自己的函数在迭代器中前进,但我想知道Python是否默认支持这样的东西

import asyncio 

async def my_iterator():

    print('A')
    yield 1
    print('B')
    yield 2
    print('C')
    yield 3 

async def main():
    print(2 in my_iterator()) # argument of type 'async_generator' is not iterable

python python-asyncio
1个回答
0
投票

in
运算符没有异步对应项。

另请注意,问题标题中提到的

__contains__
在发布的示例代码中不起作用。详细信息记录在here。简而言之,抛开字符串、序列等,用户定义的对象有三种成员资格测试方法:

  1. 如果
    __contains__
    方法存在,则调用它,
  2. 否则,如果对象是可迭代的,则会对其进行迭代,
  3. 最后的手段:测试索引 0、1、...等处的值。

生成器(即具有

yield
语句的函数)没有
__contains__
特殊方法(跳过步骤 1),这就是迭代它的原因(步骤 2)。

为了支持异步迭代,步骤 2 需要更改。我不知道是否可能,但我很确定现有的

in
不会改变。

这给我们留下了两种异步迭代选项:

  1. 编写一个带有自己的

    __aiter__
    的异步生成器(具有
    __anext__
    __contains__
    的类)。然后您可以使用现有的
    in
    。然而,在大多数情况下,不可能知道未来的价值。

  2. 只需编写一个自己的测试,就像您在问题中提到的那样:

async for v in my_async_gen():
    if v == some_value:
        print("found")
        break
else:
    print("not found")
© www.soinside.com 2019 - 2024. All rights reserved.