如何注释使用类型提示发电机的设计师吗?

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

我用的发电机,作为协同程序工作作为(在http://www.dabeaz.com/coroutines/)由大卫比兹利演讲的优秀三重描述,我无法弄清楚如何键入装饰consumer。这是我到目前为止有:

from typing import Any, Callable, Generator, Iterable

ArbGenerator = Generator[Any, Any, Any]

def consumer(fn: ❓) -> ❓:
    @wraps(fn)
    def start(*args: Any) -> ArbGenerator:
        c = fn(*args)
        c.send(None)
        return c
return start

使用示例,那种删节:

@consumer
def identity(target: ArbGenerator) -> ArbGenerator:
    while True:
        item = yield
        target.send(item)

@consumer
def logeach(label: Any, target: ArbGenerator) -> ArbGenerator:
    while True:
        item = yield
        print(label, item)
        target.send(item)

pipeline = identity(logeach("EXAMPLE", some_coroutine_sink()))

大胆标记出我不确定 - 我也不确定我定义ArbGenerator类型。 (问题是,没有(装饰)函数consumer本身类型的,我不知道mypy是分析与装饰任何发生器功能,所以这就是为什么我不能确定ArbGenerator。)

我感兴趣的是最严格的类型,东西比Any好,所以,当我撰写这些协同程序链mypy会给我很好的警告,如果链条没有树立正确的。

(Python的3.5,如果它很重要。)

python python-3.x generator type-hinting
1个回答
1
投票

作为更具体的方式,这里有几件事情可以做:

  1. 使用Callable而不是键入问号。
  2. 使用typing.Coroutinetargets并删除ArbGenerator
  3. 协同程序返回一个发电机和返回类型可能是一个Generator或它的超类型之一

你应该使用问号可调用的原因是,fn应该是在第一个调用对象,这就是为什么你与装饰加以包装。该Coroutine将调用对象的情况下创建并返回类型为/应该是显然是一个可调用对象为好。

from typing import Any, Callable,Generator, Coroutine
from functools import wraps


def consumer(fn: Callable) -> Callable:
    @wraps(fn)
    def start(*args: Any) -> Coroutine:
        c = fn(*args)  # type: Coroutine
        c.send(None)
        return c
    return start


@consumer
def identity(target: Coroutine) -> Generator:
    while True:
        item = yield
        target.send(item)

@consumer
def logeach(label: Any, target: Coroutine) -> Generator:
    while True:
        item = yield
        print(label, item)
        target.send(item)

注意:因为它是在文档中还提到,如果你想使用更精确的语法标注,您可以使用下面的语法发电机类型:

Generator[YieldType, SendType, ReturnType]

了解更多:https://docs.python.org/3/library/typing.html#typing.Generator

© www.soinside.com 2019 - 2024. All rights reserved.