dav*_*bak 6 python generator type-hinting python-3.x
我正在使用生成器作为协程,如 David Beazley 的精彩三重演示(位于http://www.dabeaz.com/coroutines/)中所述,但我不知道如何输入装饰器consumer。这是我到目前为止所拥有的:
from typing import Any, Callable, Generator, Iterable\n\nArbGenerator = Generator[Any, Any, Any]\n\ndef consumer(fn: \xe2\x9d\x93) -> \xe2\x9d\x93:\n @wraps(fn)\n def start(*args: Any) -> ArbGenerator:\n c = fn(*args)\n c.send(None)\n return c\nreturn start\nRun Code Online (Sandbox Code Playgroud)\n\n使用示例,略为:
\n\n@consumer\ndef identity(target: ArbGenerator) -> ArbGenerator:\n while True:\n item = yield\n target.send(item)\n\n@consumer\ndef logeach(label: Any, target: ArbGenerator) -> ArbGenerator:\n while True:\n item = yield\n print(label, item)\n target.send(item)\n\npipeline = identity(logeach("EXAMPLE", some_coroutine_sink()))\nRun Code Online (Sandbox Code Playgroud)\n\n粗体\xe2\x9d\x93标记了我不确定的地方 - 并且我也不确定我定义的类型ArbGenerator。(问题是,如果没有输入(装饰器)函数consumer本身,我不确定mypy是否使用该装饰器分析任何生成器函数,这就是我不确定的原因ArbGenerator。)
我对最紧密的类型感兴趣,比 更好Any,这样当我编写这些协程链时,mypy如果链设置不正确,就会给我很好的警告。
(Python 3.5,如果重要的话。)
\n作为更具体的方式,您可以执行以下操作:
使用Callable类型而不是问号。
使用typing.Coroutinefortargets并删除ArbGenerator.
协程返回一个生成器,返回类型可以是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)
Run Code Online (Sandbox Code Playgroud)
注意:正如文档中也提到的,如果您想使用更精确的语法来注释生成器类型,您可以使用以下语法:
Generator[YieldType, SendType, ReturnType]
Run Code Online (Sandbox Code Playgroud)
阅读更多:https ://docs.python.org/3/library/typing.html#typing.Generator
| 归档时间: |
|
| 查看次数: |
1544 次 |
| 最近记录: |