“ with”语句是否支持类型提示?


16

您可以为使用with语法定义的变量定义类型提示吗?

with example() as x:
    print(x)

我想在上面键入提示以说这x是一个str(作为示例)。

我发现的唯一解决方法是使用中间变量,但这感觉很hack。

with example() as x:
    y: str = x
    print(y)

我在打字文档中找不到示例。


6
类型检查器是否应推断出x类型为example().__enter__()?的返回类型?
pschill

2
x当它只是返回类型时,为什么要注释example.__enter__?理想情况下,您已经注释了该方法/函数。
a_guest

1
x不是...的返回值example;这是的返回值example().__enter__()
chepner

我发现的大多数方法都没有为返回值定义类型提示。
Reactgular

1
@Reactgular然后解决方案是为该函数创建一个存根文件,以便类型检查器可以推断类型。通常,您在API边界而不是内部进行注释。在这种情况下,类型显然来自example。注释example.__enter__意味着一个注释,而使用您的方法时,您将必须在使用该上下文管理器的所有位置进行注释,并且一般而言,如果未提供API,则用户应该如何知道API的返回类型是什么?
a_guest

Answers:


11

PEP 526(已在Python 3.6中实现)允许您注释变量。您可以使用例如

x: str
with example() as x:
    [...]

要么

with example() as x:
    x: str
    [...]

这也适用于其他代码块,例如for。好答案,谢谢。
Reactgular

如果上下文管理器没有提示该__enter__方法将返回什么,则键入x没有任何作用。mypy很乐意允许将任何类型的值绑定到x
chepner

@chepner是的,您是对的。PyCharm识别xstr在这两种情况下,但是mypy没有。
pschill

14

通常,类型注释位于API边界。在这种情况下,应从推断类型example.__enter__。如果该函数未声明任何类型,则解决方案是创建一个相应的存根文件,以帮助类型检查器推断该类型。

具体来说,这意味着创建一个.pyiExample导入模块具有相同词干的文件。然后可以添加以下代码:

class Example:
    def __enter__(self) -> str: ...
    def __exit__(self, exc_type, exc_value, exc_traceback) -> None: ...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.