Я использую API, который использует подсказки типов, возвращаемые функциями, для хранения информации (я знаю, что это не рекомендуется, я не могу контролировать API):
my_hint: StringProperty()
Это работает, но исключает возможность использовать подсказку типа в качестве фактической подсказки типа.
Я ищу способ создать оболочку, которая поддерживала бы тот же синтаксис, что и в приведенном выше примере, но при указании типа назначала бы другой, более полезный тип (в данном случае тип str
).
Моя первая идея заключалась в том, чтобы сделать что-то вроде этого:
if typing.TYPE_HINTING:
def StringProperty() -> str: pass
my_hint: StringProperty()
Однако это не работает: вместо my_hint
присваивается тип Any
.
Есть ли способ сделать это, учитывая, что я не могу изменить способ работы API?
@mkrieger1 К сожалению, не думаю, что typing.Annotated
здесь поможет. Для ясности я опустил детали API Blender, но, по сути, свойства классов определяются с помощью приведенного выше синтаксиса, а затем эти классы регистрируются в Blender. Когда это происходит, Blender сканирует атрибут __annotations__
класса и создаёт типы Blender Property
в соответствии с ними. Это не очень хороший и интуитивный способ работы, но, к сожалению, так оно и есть. Я ищу способ вернуть подсказку полезного типа из функции, чтобы сохранить тот же синтаксис.
@StrikeDigital да, IIUUC, это то, для чего Annotated
предполагается, но блендер должен это поддерживать. Какой беспорядок.
Используйте TYPE_CHECKING при вводе для условного импорта:
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Any
StringProperty = str
else:
from some_api import StringProperty
my_hint: StringProperty = StringProperty()
Во время проверки типа StringProperty присваивается псевдоним str.
Во время выполнения StringProperty использует фактическую функцию из API.
При этом сохраняется синтаксис, а подсказка типа ведет себя как str во время проверки типа при правильном вызове функции API.
Подробнее об этом написано в PEP 484 — Печатание.
Удачи!
Спасибо, однако, похоже, это не работает. Если я вставлю этот код, моя IDE покажет, каким типом my_hint
будет Any
. Пример: ibb.co/j3CJzW6
Да, ты прав. Я сожалею о том, что; Я обновил ответ..
Хм, теперь это работает как подсказка типа, но для работы с API необходимо вызвать StringProperty()
как функцию в последней строке.
Я считаю, что последнее изменение кода должно дать ответ.
Это близко, но подсказку типа необходимо присвоить результату StringProperty()
(как в примере из вопроса). Это нестандартно, но, к сожалению, именно так работает API :/. Спасибо!
(Based on a comment of yours, I assume you are using Pyright/Pylance on VSCode.)
Вот моя рекомендация: вообще отказаться от статической проверки типов.
StringProperty()
— это выражение вызова, которое не будет распознаваться как допустимое выражение типа средствами проверки типов, совместимыми со спецификацией (включая Pyright), независимо от того, что вы делаете во время выполнения.
Любое использование синтаксиса name: expression
без указания типа не рекомендуется. Рассматриваемая библиотека/фреймворк сделала необычный и неудачный выбор.
Я не совсем понимаю, что делает этот API, но, возможно, вы могли бы использовать
typing.Annotated
.