- Модуль typing в Python.
- Поддержка аннотации типов в Python.
- Содержание:
- Использование псевдонимов типов в модуле typing .
- Аннотация отдельных подтипов typing.NewType .
- Аннотация функций обратного вызова typing.Callable .
- Аннотация универсальных типов.
- Аннотация универсальных типов, определяемые пользователем.
- Применение аннотации typing.Any .
- Номинальные и структурные подтипы.
- Эффект печатающегося текста
- Сценарий JavaScript печатающий текст
- Эффекты текста при совместном использовании JavaScript и CSS-анимации
Модуль typing в Python.
Поддержка аннотации типов в Python.
Внимание. Интерпретатор Python не проверяет и не принимает во внимание аннотации типов функций и переменных. Их могут использовать сторонние инструменты, такие как средства проверки типов, IDE, линтеры и т. д.
Модуль typing обеспечивает поддержку выполнения аннотации типов. Наиболее фундаментальная поддержка состоит из типов typing.Any , typing.Union , typing.Tuple , typing.Callable , typing.TypeVar и typing.Generic .
Для упрощенного введения в аннотации типов смотрите материал «Аннотации типов в функциях Python».
Функция ниже принимает и возвращает строку и аннотируется следующим образом:
В функции greeting() ожидается, что имя аргумента будет иметь тип str и возвращаемый тип ожидается str . Подтипы принимаются в качестве аргументов типов. Например переменная списка lst , состоящий из значений int будет аннотироваться как lst: list[int] .
Примечание. Модуль typing определяет несколько типов, которые являются подклассами уже существующих классов стандартной библиотеки, и которые также расширяют typing.Generic для поддержки типов переменных внутри [] скобок. С версии Python 3.9, классы стандартной библиотеки были расширены для поддержки синтаксиса [] и эти типы стали избыточными.
Избыточные типы устарели в Python 3.9, но интерпретатор не будет выдавать предупреждений DEPRECATED . Ожидается, что средства проверки типов будут отмечать устаревшие типы, когда проверяемый код нацелен на версию Python 3.9 или новее.
Устаревшие типы будут удалены из модуля typing в первой версии Python, выпущенной через 5 лет после выпуска Python 3.9.0.
Содержание:
Использование псевдонимов типов в модуле typing .
Псевдоним типа определяется путем присвоения типа псевдониму. В этом примере Vector и list[float] будут рассматриваться как взаимозаменяемые синонимы:
Псевдонимы типов полезны для упрощения сигнатур сложных типов. Например:
Обратите внимание, что указание типа None является особым случаем и заменяется type(None) .
Аннотация отдельных подтипов typing.NewType .
Используйте вспомогательную функцию `typing.NewType() для создания отдельных типов:
Средство проверки статического типа будет рассматривать новый тип, как если бы он был подклассом исходного типа. Такое поведение полезно для выявления логических ошибок:
По-прежнему можно выполнять все операции с int с переменной типа UserId , но результат всегда будет иметь тип int . Это позволяет передать UserId везде, где можно ожидать int , но предотвратит случайное создание UserId недопустимым способом:
Обратите внимание, что эти проверки выполняются только средством проверки типов. Во время выполнения оператор Derived= NewType(‘Derived’, Base) сделает Derived функцией, которая немедленно возвращает любой переданный ей параметр. Это означает, что выражение Derived(some_value) не создает новый класс и не вводит никаких накладных расходов, помимо обычных вызовов функции.
Точнее, выражение some_value is Derived(some_value)` всегда истинно во время выполнения.
Это также означает, что невозможно создать подтип Derived , т. к. во время выполнения это функция идентификации, а не фактический тип:
Однако можно создать typing.NewType() на основе производного NewType :
и проверка типов для ProUserId будет работать так, как ожидалось.
Примечание. Напомним, что использование псевдонима типа объявляет, что два типа эквивалентны друг другу. Выполнение Alias = Original заставит средство проверки статического типа обрабатывать псевдоним как полностью эквивалентный оригиналу во всех случаях. Это полезно, когда необходимо упростить сигнатуры сложных типов.
Напротив, typing.NewType объявляет один тип подтипом другого. Выполнение Derived = NewType(‘Derived’, Original) заставит средство проверки аннотации типов рассматривать Derived как подкласс Original , это означает, что значение типа Original не может использоваться в местах, где ожидается значение типа Derived . Такое поведение полезно, когда необходимо предотвратить логические ошибки с минимальными затратами времени выполнения.
Аннотация функций обратного вызова typing.Callable .
Платформы, ожидающие функций обратного вызова для определенных сигнатур, могут создать аннотацию типа с помощью Callable[[Arg1Type, Arg2Type], ReturnType] .
Можно объявить возвращаемый тип вызываемого объекта без указания сигнатуры вызова, подставив буквальное многоточие вместо списка аргументов в аннотации типа: Callable[. ReturnType] .
Аннотация универсальных типов.
Так как информация о типах объектов, хранящихся в контейнерах, не может быть статически представлена универсальным способом, для обозначения ожидаемых типов элементов контейнера, абстрактные базовые классы были расширены.
Универсальные шаблоны типов можно параметризовать с помощью новой фабрики, доступной для ввода, которая называется typing.TypeVar .
Аннотация универсальных типов, определяемые пользователем.
Пользовательский класс может быть определен как универсальный класс.
Generic[T] как базовый класс определяет, что класс LoggedVar принимает единственный параметр типа T . Это также делает T действительным как тип в теле класса.
Базовый класс typing.Generic определяет __class_getitem__() , так что LoggedVar[t] действителен как тип:
Универсальный тип может иметь любое количество переменных типа, а переменные типа могут быть ограничены:
Все аргументы переменной типа для typing.Generic должны быть разными. Таким образом, следующее неверно:
С typing.Generic можно использовать множественное наследование :
При наследовании от универсальных классов некоторые переменные типа могут быть исправлены:
В этом случае MyDict имеет единственный параметр T .
Использование универсального класса без указания параметров типа предполагает typing.Any для каждой позиции. В следующем примере MyIterable не является универсальным, а неявно наследуется от Iterable[Any] :
Также поддерживаются определенные пользователем псевдонимы универсального типа. Примеры:
Изменено в Python 3.7: typing.Generic больше не имеет собственного метакласса.
Пользовательский универсальный Generic класс может иметь ABC в качестве базовых классов без конфликта метаклассов. Универсальные метаклассы не поддерживаются. Результат параметризации универсальных шаблонов кэшируется, и большинство типов в модуле typing являются хешируемыми и сопоставимыми для проверки равенства.
Применение аннотации typing.Any .
Особый тип аннотации typing.Any . Средство проверки статического типа будет рассматривать каждый тип как совместимый с Any и Any как совместимый с каждым типом.
Это означает, что можно выполнить любую операцию или вызов метода для значения типа Any и присвоить его любой переменной:
Обратите внимание, что при присвоении значения типа Any более точному типу, проверка типов выполняться не будет. Например, средство проверки аннотации не сообщило об ошибке при присвоении a параметру s , даже если s был объявлен как имеющий тип str и получил значение int во время выполнения!
Кроме того, все функции без возвращаемого типа или типов параметров неявно по умолчанию будут использовать Any:
Такое поведение позволяет использовать typing.Any в качестве аварийного выхода, когда необходимо смешивать динамически и статически типизированный код.
Сравните поведение typing.Any с поведением object : Подобно Any , каждый тип является подтипом object . Однако, в отличие от Any , обратное неверно: object не является подтипом любого другого типа.
Это означает, что, когда типом значения является объект, то средство проверки типов отклоняет почти все операции с ним, и присвоение его переменной (или использование в качестве возвращаемого значения) более специализированного типа является ошибкой типа. Например:
Используйте object , для указания значения любого типа безопасным способом, а typing.Any , для динамически типизируемых значений.
Номинальные и структурные подтипы.
Первоначально определи систему статических типов Python, как использование номинальных подтипов. Это означает, что класс A разрешен там, где ожидается класс B тогда и только тогда, когда A является подклассом B .
Это требование ранее также применялось к абстрактным базовым классам, таким как Iterable . Проблема с этим подходом заключается в том, что класс должен быть явно помечен для их поддержки, что не является питоническим и отличается от того, что обычно делают в идиоматическом динамически типизированном коде Python. Например:
Однако пользователи могут писать приведенный выше код без явных базовых классов в определении класса, что позволяет средствам проверки статических типов неявно рассматривать Bucket как подтип Sized и Iterable[int] . Это называется структурным подтипом или статической утиной типизацией:
Более того, создавая подклассы для специального класса Protocol , пользователь может определять новые настраиваемые протоколы, чтобы в полной мере насладиться структурным подтипом.
Источник
Эффект печатающегося текста
С помощью эффектов и анимации текста можно сделать занимательные веб-страницы, и в этом уроке мы рассмотрим один из таких эффектов, а именно, разберем, как сделать печатающийся текст с помощью JavaScript.
| Опубликовал: | Paul.Z |
| Автор: | Paul Z |
| Опубликовано: | 11.06.2020 |
| Просмотров: | 2906 |
| Рейтинг: |