осмотрите. подпись с PEP 563 - PullRequest
0 голосов
/ 20 ноября 2018

Следующий код:

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, как без него?

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Смысл использования PEP 536 состоит в том, чтобы не оценивать аннотации, если в этом нет необходимости.Подпись просто сообщает об аннотациях.

Если для ваших целей вам необходимо разрешить аннотации, вы должны сделать это самостоятельно.PEP 536 сообщает документам о том, как вы это делаете :

Для кода, использующего подсказки типов, функция typing.get_type_hints(obj, globalns=None, localns=None) правильно вычисляет выражения обратно из строковой формы.

[...]

Для кода, который использует аннотации для других целей, достаточно обычного вызова eval (ann, globals, localals) для разрешения аннотации.

Вы можетедаже используйте 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 не использовался.

0 голосов
/ 23 ноября 2018

Во-первых, давайте запустим другой пример:

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'))])

То есть вы не получите то же самое Signature здесь.Один дает вам реальный класс, а другой - typing.ForwardRef классу.

...