代码之家  ›  专栏  ›  技术社区  ›  Tobias Hermann

检查。与PEP 563签署

  •  4
  • Tobias Hermann  · 技术社区  · 6 年前

    以下代码:

    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 – Postponed Evaluation of Annotations :

    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就像没有它?

    2 回复  |  直到 6 年前
        1
  •  3
  •   Martijn Pieters    6 年前

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

    如果出于您的目的,需要解析注释,那么您必须自己这样做。PEP 536讲述 documents how you do this 以下内容:

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

    […]

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

    你甚至可以使用 typing.get_type_hints() function 分配回 __annotations__ 在获得签名之前:

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

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

        2
  •  1
  •   yorodm    6 年前

    首先,让我们运行一个不同的示例:

    signature: inspect.Signature = inspect.signature(Example)
    print(signature)
    print(Example.__annotations__)
    

    印刷品:

    (a: str)
    OrderedDict([('a', <class 'str'>)])
    

    到目前为止很好,我们有或 Signature 以及我们的 __anotations__ 正如我们预料的那样。

    现在,让我们对第二个示例进行同样的操作,它打印:

    (a: 'str')
    OrderedDict([('a', ForwardRef('str'))])
    

    所以你不能 相同的 签名 在这里。一个给你实际的课程,另一个给你 typing.ForwardRef 上课。