首页 > 解决方案 > 使用 PEP 563 检查.signature

问题描述

以下代码:

import inspect
from typing import NamedTuple

class Example(NamedTuple):
    a: str

if __name__== "__main__":
    signature: inspect.Signature = inspect.signature(Example)
    print(signature)

输出:

(a: str)

但是,当启用PEP 563 – 延迟评估注释时:

from __future__ import annotations
import inspect
from typing import NamedTuple

class Example(NamedTuple):
    a: str

if __name__== "__main__":
    signature: inspect.Signature = inspect.signature(Example)
    print(signature)

输出是:

(a: 'str')

inspect.Signature如果没有它,我怎样才能获得与 PEP 563完全相同的类型对象?

标签: pythonpython-3.xtypespython-3.7static-typing

解决方案


使用 PEP 536 的目的是除非需要,否则不要评估注释。签名仅报告注释。

如果出于您的目的需要解决注释,则必须自己解决。PEP 536 告诉文档您如何执行此操作

对于使用类型提示的代码,该typing.get_type_hints(obj, globalns=None, localns=None)函数正确地从其字符串形式返回表达式。

[...]

对于将注释用于其他目的的代码,常规的 eval(ann, globals, locals) 调用足以解析注释。

您甚至可以在获取签名之前使用该typing.get_type_hints()函数进行分配:__annotations__

import typing

Example.__new__.__annotations__ = typing.get_type_hints(Example.__new__)
signature: inspect.Signature = inspect.signature(Example)

即使from __future__ import annotations没有使用,这样做也是安全的。


推荐阅读