上下文管理器的类型提示 [英] Type hints for context manager

查看:37
本文介绍了上下文管理器的类型提示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个 pyplot 图形的上下文管理器,本质上是这样的:

I would like to have a context manager for pyplot figures essentially like so:

from contextlib import contextmanager
import matplotlib.pyplot as plt

@contextmanager
def subplots():
  (fig, ax) = plt.subplots()
  try:
    yield (fig, ax)
  finally:
    plt.close(fig)

可以为返回的元组实现类型提示吗?天真

Can type hinting be implemented for the returned tuple? The naive

import typing
def subplots() -> typing.Tuple[plt.Figure, plt.Axes]

不起作用.

推荐答案

你的函数实际上不是返回一个元组.相反,它是产生一个——如果你在没有上下文管理器的情况下调用subplots(),你将得到一个生成器对象.因此,您需要对其进行注释:

Your function is not actually returning a tuple. Rather, it's yielding one -- if you call subplots() without the context manager, you'll get back a generator object. So, you'll need to annotate it as such:

from typing import Tuple, Generator
from contextlib import contextmanager
import matplotlib.pyplot as plt

@contextmanager
def subplots() -> Generator[Tuple[plt.Figure, plt.Axes], None, None]:
  (fig, ax) = plt.subplots()
  try:
    yield (fig, ax)
  finally:
    plt.close(fig)

您可以在 mypy 文档中找到有关 Generator 的更多信息,但简而言之,它接受三种类型:生成器产生的任何类型,生成器可以发送的任何值的类型,以及生成器最终返回的任何值的类型.我们这里不关心后两者,所以我们将它们保留为 None.

You can find more information about Generator in the mypy docs, but in short, it accepts three types: the type of whatever the generator yields, the type of whatever value your generator can be sent, and the type of whatever value your generator finally returns. We don't care about the latter two here, so we leave them as None.

虽然这种类型最终会让人感觉笨重.更简洁的替代方法是将返回类型注释为迭代器:

This type does end up being a feeling clunky though. A more concise alternative is to annotate the return type as being an Iterator instead:

from typing import Tuple, Iterator
from contextlib import contextmanager
import matplotlib.pyplot as plt

@contextmanager
def subplots() -> Iterator[Tuple[plt.Figure, plt.Axes]]:
  (fig, ax) = plt.subplots()
  try:
    yield (fig, ax)
  finally:
    plt.close(fig)

这是可行的,因为所有生成器实际上都是迭代器——生成器是迭代器的子类型.所以选择更通用的返回类型就可以了.

This works because all Generators are actually Iterators -- Generator is a subtype of Iterator. So it's fine to pick the more general return type.

这篇关于上下文管理器的类型提示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆