Как внедрить аннотации переменных класса в Python 3.7+? - PullRequest
0 голосов
/ 08 октября 2018

В Python 3.7 статические поля могут быть аннотированы следующим синтаксисом, определенным в PEP 526 :

class A:
   foo: int

Как я могу сделать эти аннотации позже, после определения класса?Я ожидаю, что сработает следующее:

A.bar : float

Однако, похоже, что оно не имеет идентичного эффекта с первым кодом.Когда мы смотрим на A __dict___, эти два фрагмента не имеют одинакового эффекта.

После примера 1 и после примера 2 мы получаем идентичные __dict__то есть второй пример должен показывать эффект где-то еще.Созданное изречение:

>> pprint(A.__dict__):
mappingproxy({'__annotations__': {'foo': <class 'int'>}, # <-!
              '__dict__': <attribute '__dict__' of 'A' objects>,
              '__doc__': None,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'A' objects>})

Я не думаю, что редактирование __annotations__ - это «хороший» метод достижения того, чего я хочу, особенно потому, что я не уверен, что это единственный случай, когда foo зарегистрирован.

Как правильно сделать это?

1 Ответ

0 голосов
/ 08 октября 2018

Информация, используемая в переменных аннотациях для атрибутов экземпляра и класса, хранится в отображении __annotations__ класса, словаре, доступном для записи.

Если вы хотите добавить информацию, хранящуюся там, то простодобавьте новую информацию непосредственно в это отображение:

A.__annotations__['bar'] = float

Аннотация A.bar: float отбрасывается Python , так как нет выделенного места для хранения информации для аннотированных выражений;решение о том, имеет ли это выражение смысл, зависит от реализации средства проверки статического типа.

См. Эффекты времени выполнения аннотаций типов section из PEP 526 -- Синтаксис для аннотаций переменных , документ, который определяет этот синтаксис:

Кроме того, на уровне модуля или класса, если аннотируемый элемент представляет собой простое имя затем он и аннотация будут сохранены в атрибуте __annotations__ этого модуля или класса (искаженного, если он частный) в виде упорядоченного отображения имен в оценочные аннотации.

и из Аннотированные операторы присваивания раздел справочной документации Python:

Для простых имен в качестве целей назначения, если в области действия класса или модуля аннотации оцениваются и сохраняются вспециальный атрибут класса или модуля __annotations__, который представляет собой словарь, сопоставляющий имена переменных (искаженные, если они закрытые) с оцененными аннотациями.Этот атрибут доступен для записи и автоматически создается в начале выполнения тела класса или модуля, если аннотации обнаруживаются статически.

A.bar - это не простое имя, это выражение, поэтому ононе хранится;если вы хотите сохранить эту информацию в отображении __annotations__ для доступа во время выполнения, то настройка вручную - единственная опция.

...