为ndb.tasklets添加类型注释

6
GvRs App Engine ndb Library以及monocle和 - 据我所知 - 现代Javascript使用生成器使异步代码看起来像阻塞式代码。
事物被装饰为@ndb.tasklet。当它们想要将执行权交还给运行循环时,它们会yield,当它们准备好结果时,它们会raise StopIteration(value)(或别名ndb.Return):
@ndb.tasklet
def get_google_async():
    context = ndb.get_context()
    result = yield context.urlfetch("http://www.google.com/")
    if result.status_code == 200:
        raise ndb.Return(result.content)
    raise RuntimeError

使用这样的函数,您会得到一个ndb.Future对象,并在其上调用get_result()函数以等待结果并获取它。例如:
def get_google():
    future = get_google_async()
    # do something else in real code here
    return future.get_result()

这一切都很好,但如何添加类型注释呢?正确的类型为:
  • get_google_async() -> ndb.Future(通过yield)
  • ndb.tasklet(get_google_async) -> ndb.Future
  • ndb.tasklet(get_google_async).get_result() -> str
到目前为止,我只能使用cast来转换异步函数的类型。
def get_google():
    # type: () -> str
    future = get_google_async()
    # do something else in real code here
    return cast('str', future.get_result())

不幸的是,这不仅涉及到urlfetch,还涉及到数百种方法 - 主要是ndb.Model的方法。

如果您使用实体,结果不是自动转换的吗?https://cloud.google.com/appengine/docs/standard/python/ndb/creating-entities - David
1个回答

1

get_google_async 本身是一个生成器函数,因此类型提示可以是 () -> Generator[ndb.Future, None, None]

至于 get_google,如果你不想进行转换,类型检查可能会起作用。

像这样:

def get_google():
    # type: () -> Optional[str]
    future = get_google_async()
    # do something else in real code here
    res = future.get_result()
    if isinstance(res, str):
        return res
    # somehow convert res to str, or
    return None

所以每当我写future.get_result()时,我都必须进行某种类型推断魔法?我不能教会mypy等工具future.get_result()将返回Optional[str]吗? :-( - max
ndb.Future 本身并不总是返回 Optional[str],因此在每个函数中定义类型提示是很自然的事情,也许...?就像你提到的 ndb.Model。例如,count_async().get_result() 返回 int,而不是 str。 - taka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接