Есть ли способ использовать подсказки типа в обратно совместимом коде в Python? - PullRequest
0 голосов
/ 08 мая 2018

Я пишу некоторый код, который я хочу запускать на предыдущих версиях Python до того, как была добавлена ​​подсказка по типу, без необходимости отдельной базы кода. Есть ли простой способ сделать это?

Аналогично тому, как from __future__ import print_function позволит вам использовать print() в коде Python 2, есть ли from __future__ import type_hints?

Принятый ответ на дубликат вопроса действительно дает один способ заставить его работать в 2.7, но он не говорит, должно ли это также хорошо работать в Python 3. Я собираюсь спросить в комментарии ответа, но мой вопрос ищет что-то совместимое с Python 2 и более ранними версиями Python 3.

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Чтобы использовать подсказки типов полностью обратно-совместимым способом, вам нужно ...

  1. Всегда используйте синтаксис на основе комментариев : Python 2 не поддерживает аннотации функций; Python 3.0-3.5 не поддерживает аннотации переменных.
  2. Установить бэкпорт модуля ввода при использовании Python 2.7 и 3.0 - 3.4. Модуль ввода был добавлен в стандартную библиотеку в Python 3.5 и должен быть установлен pip для более ранних версий Python.

Еще одно осложнение заключается в том, что модуль ввода несколько раз обновлялся новыми типами, поскольку он был добавлен в стандартную библиотеку в Python 3.5.0 - такие типы, как ClassVar, Deque, Protocol, Text, Type, и это лишь некоторые из них. .

Если вы хотите использовать эти типы и по-прежнему поддерживать Python 3.5 и 3.6, дополнительно установите модуль typing_extensions . Вы можете найти полный список поддерживаемых типов в github repo .

Обычно, если вы хотите использовать любой из перечисленных выше типов репозитория github и поддерживать Python 3.5.0 - 3.6.x, всегда импортируйте их из typing_extensions вместо typing.


Некоторые дополнительные сведения и предостережения, которые могут вас не беспокоить:

  1. О typing_extensions:

    Если вы планируете использовать typing_extensions, также обратите особое внимание на необходимость поддержки Python 3.5.0 - 3.5.2. Модуль ввода подвергся нескольким, часто существенным, внутренним изменениям с тех пор, как он был впервые выпущен в Python 3.5.0.

    Модуль typing_extension пытается соединить эти разные внутренние API в разумном порядке, но всегда есть вероятность, что что-то упустили. Последние второстепенные версии Python 3.5 и Python 3.6, тем не менее, намного более современны, и поэтому с гораздо меньшей вероятностью могут возникнуть проблемы.

    (Вы также можете уйти, не используя typing_extensions, если хотите поддерживать только последние минорные версии Python 3.5 и 3.6: несколько типов, отсутствующих в Python 3.5.0 и Python 3.6.0 были добавлены позже. Но, честно говоря, трудно отследить, что было добавлено, когда, так что может быть безопаснее просто по умолчанию использовать typing_extensions и не беспокоиться об этом.)

  2. О mypy:

    Если вы хотите использовать mypy, имейте в виду, что mypy может быть запущена только с использованием не EOL-версий Python 3. Поэтому на момент написания Python 3.4+.

    Однако сам mypy можно использовать для анализа кода Python 2.7+.

  3. О типах и Python 3.0 - 3.2:

    Mypy и большинство других PEP 484-совместимых инструментов проверки типов используют typhed , набор аннотаций типов для стандартной библиотеки и популярных сторонних библиотек.

    Typeshed отслеживает, когда функции и классы были добавлены в стандартную библиотеку. Таким образом, вы можете попросить такие инструменты, как mypy, убедиться, что ваш код работает с конкретными версиями Python и что вы случайно ничего не импортировали из будущего.

    Тем не менее, typhed отслеживает эту информацию только для Python 2.7 и 3.3+. Таким образом, вы должны быть осторожны, если вы нацелены именно на Python 3.0 - 3.2.

  4. О unicode_literals и mypy / typeshed:

    Некоторые люди рекомендуют использовать unicode_literals в качестве метода, помогающего совместимости с Python 2/3.

    Тем не менее, я считаю, что использование unicode_literals вызывает ряд проблем с typehed или mypy. Я забыл точные детали, но в результате вам, вероятно, лучше не использовать его (по крайней мере, пока).

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

    • Используйте typing.Text, когда что-то ДОЛЖНО быть unicode. Этот тип имеет псевдоним unicode в Python 2 и str в Python 3.
    • Используйте bytes (или, может быть, bytearray?), Когда что-то ДОЛЖНО быть байтами. Обязательно имейте в виду, что bytes ведет себя немного по-разному между Python 2 и 3.
    • Используйте str, когда это значение должно быть таким, какое str означает для этой конкретной версии Python.

    Если вам нужно написать функцию, которая должна работать с несколькими типами строк, вы можете сделать это с осторожным использованием Union или AnyStr.

0 голосов
/ 08 мая 2018

Принятый ответ на дублированный вопрос представляется верным для Python 3.x, где x <5, по крайней мере, для mypy. </p>

С Mypy Docs :

Пример ниже иллюстрирует аннотацию типа функции Python 2 синтаксис. Этот синтаксис также действителен в режиме Python 3:

from typing import List

def hello(): # type: () -> None
    print 'hello'

class Example:
    def method(self, lst, opt=0, *args, **kwargs):
        # type: (List[str], int, *str, **bool) -> int
        """Docstring comes after type comment."""

Однако до Python 3.5 вам нужно pip install typing.

...