您链接的问题提出了一些极其肮脏的黑客,但它似乎不再起作用。这么简单的情况下根本就没有必要。此外,说实话,我无法在任何mypy
版本从0.800
(足够老了,考虑到链接的答案是最近的),所以也许从来没有工作过。
为了便于阅读,我减少了您的代码示例,使其仅包含最小的返回值。
变体 1:使用条件导入和字符串注释
import psycopg2
from typing import Optional, TYPE_CHECKING
if TYPE_CHECKING:
from psycopg2 import connection
def get_connection() -> Optional['connection']:
return psycopg2.connect(...)
这很简单:mypy
知道什么connection
是(在存根中定义);运行时不会尝试学习一些东西connection
因为它只看到一个字符串。
变体 2:使用条件导入和注释 future
from __future__ import annotations
import psycopg2
from typing import Optional, TYPE_CHECKING
if TYPE_CHECKING:
from psycopg2 import connection
def get_connection() -> Optional[connection]:
return psycopg2.connect(...)
未来进口的文件 https://docs.python.org/3/library/__future__.html。这与直接使用字符串非常相似,但看起来更好并且更方便,IMO。
变体 3:使用字符串注释,但避免条件导入
import psycopg2
from typing import Optional
def get_connection() -> Optional['psycopg2.connection']:
return psycopg2.connect(...)
变体 4:使用 future 注释,但避免条件导入
from __future__ import annotations
import psycopg2
from typing import Optional
def get_connection() -> Optional[psycopg2.connection]:
return psycopg2.connect(...)
变体 3 和 4 没有暴露这一点connection
仅存根,将其隐藏为实现细节。您可能更愿意明确说明这一点 - 然后使用 1 或 2。
修改以使用当前功能
这是我最喜欢的。 Union 语法在 python 3.10+ 中有效,因此如果您使用较旧的语法 - 您可能需要坚持使用Optional
如上所述,以保持一致性。然而,annotations
future-import 使这个表达式有效地成为一个字符串,因此如果您的工具不执行任何运行时类型自省 - 您仍然可以在旧版本上使用管道联合语法。请注意typing.get_type_hints
在 3.10 之前的 python 上,类似的实用程序将因此语法而失败。
from __future__ import annotations
import psycopg2
def get_connection() -> psycopg2.connection | None:
return psycopg2.connect(...)