Как назначить подсказку типа из подсказки типа возвращаемого значения функции

Я использую API, который использует подсказки типов, возвращаемые функциями, для хранения информации (я знаю, что это не рекомендуется, я не могу контролировать API):

my_hint: StringProperty()

Это работает, но исключает возможность использовать подсказку типа в качестве фактической подсказки типа.

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

Моя первая идея заключалась в том, чтобы сделать что-то вроде этого:

if typing.TYPE_HINTING:
    def StringProperty() -> str: pass

my_hint: StringProperty()

Однако это не работает: вместо my_hint присваивается тип Any.

Есть ли способ сделать это, учитывая, что я не могу изменить способ работы API?

Я не совсем понимаю, что делает этот API, но, возможно, вы могли бы использовать typing.Annotated.

mkrieger1 13.07.2024 23:57

@mkrieger1 К сожалению, не думаю, что typing.Annotated здесь поможет. Для ясности я опустил детали API Blender, но, по сути, свойства классов определяются с помощью приведенного выше синтаксиса, а затем эти классы регистрируются в Blender. Когда это происходит, Blender сканирует атрибут __annotations__ класса и создаёт типы Blender Property в соответствии с ними. Это не очень хороший и интуитивный способ работы, но, к сожалению, так оно и есть. Я ищу способ вернуть подсказку полезного типа из функции, чтобы сохранить тот же синтаксис.

Strike Digital 14.07.2024 00:14

@StrikeDigital да, IIUUC, это то, для чего Annotated предполагается, но блендер должен это поддерживать. Какой беспорядок.

juanpa.arrivillaga 14.07.2024 00:17
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
76
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Используйте 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

Strike Digital 14.07.2024 00:19

Да, ты прав. Я сожалею о том, что; Я обновил ответ..

Max Haase 14.07.2024 00:30

Хм, теперь это работает как подсказка типа, но для работы с API необходимо вызвать StringProperty() как функцию в последней строке.

Strike Digital 14.07.2024 00:38

Я считаю, что последнее изменение кода должно дать ответ.

Max Haase 14.07.2024 00:48

Это близко, но подсказку типа необходимо присвоить результату StringProperty() (как в примере из вопроса). Это нестандартно, но, к сожалению, именно так работает API :/. Спасибо!

Strike Digital 14.07.2024 01:03
Ответ принят как подходящий

(Based on a comment of yours, I assume you are using Pyright/Pylance on VSCode.)

Вот моя рекомендация: вообще отказаться от статической проверки типов.

StringProperty() — это выражение вызова, которое не будет распознаваться как допустимое выражение типа средствами проверки типов, совместимыми со спецификацией (включая Pyright), независимо от того, что вы делаете во время выполнения.

Любое использование синтаксиса name: expression без указания типа не рекомендуется. Рассматриваемая библиотека/фреймворк сделала необычный и неудачный выбор.

Другие вопросы по теме