Как я могу создать рекурсивный тип Python, определенный для нескольких псевдонимов? - PullRequest
1 голос
/ 14 октября 2019

Мне нужна эта структура логического типа:

ObjectType = Dict[str, 'EntryType']
ListType = List['EntryType']
EntryType = Union[str, 'ListType', 'ObjectType']

mypy сообщает об этих ошибках:

mdl/structure.py:7: error: Cannot resolve name "ObjectType" (possible cyclic definition)
mdl/structure.py:7: error: Cannot resolve name "EntryType" (possible cyclic definition)
mdl/structure.py:8: error: Cannot resolve name "ListType" (possible cyclic definition)
...

Есть ли способ кодировать этот рекурсивный тип данных?

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

Ответы [ 2 ]

1 голос
/ 14 октября 2019

Рекурсивные типы еще не поддерживаются в mypy . Они определенно включены в план, хотя я не совсем уверен, когда начнутся работы по внедрению. Это должно было начаться в начале этого года, но обязательный рефакторинг фазы семантического анализа (который внес много внутренних изменений, необходимых для чистой поддержки рекурсивных типов), занял больше времени, чем ожидалось, поэтому я не уверен, что новыйСрокиМожет быть, когда-нибудь в следующем полугодии или около того?

Возможный альтернативный подход, который вы могли бы рассмотреть, - это использование TypedDicts , которое позволяет назначать определенные типы определенным клавишам. Это особенно полезно, если вы уже знаете заранее, какова будет структура ваших входных диктов - если вы точно знаете, какие ключи будут иметь ваши ObjectTypes, и какие именно они будут отображаться. Библиотеки, такие как pydantic , также полезны здесь, если вы предпочитаете работать с объектами вместо диктов и предпочитаете не писать кучу проверочной логики.

Прагматично, если ваша структура диктов действительнов свободной форме, возможно, лучше всего пойти с ObjectType = Dict[str, object]. В конце концов, чтобы точно определить, с каким EntryType вы имеете дело, вам все равно придется добавить несколько проверок экземпляра, чтобы сузить тип. Таким образом, если начинать с object вместо Union[str, ListType, ObjectType] будет слегка раздражающим, это может быть не слишком большим наложением в зависимости от того, что вы делаете.

1 голос
/ 14 октября 2019

mypy не поддерживает рекурсивные типы: https://github.com/python/mypy/issues/731

Ваше определение типа невозможно для mypy, и не для любого другого средства проверки типов, которое я знаю. Встраивание отдельных типов даст вам бесконечно длинные определения типов, так как это рекурсивно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...