Автор оригинала: Pankaj Kumar.
Введен с момента Python 3.5, Python’s Набрав модуль Попытки обеспечить способ намеканий типов, чтобы помочь чеканам статическим типом и линтами точно предсказать ошибки.
Из-за Python, необходимого для определения типа объектов во время выполнения, иногда разработчикам становится очень сложно выяснить, что именно происходит в коде.
Даже внешние шашки типа любят Pycharm Ide не производите лучшие результаты; В среднем только прогнозируют ошибки правильно около 50% времени, согласно это Ответ на Stackoverflow.
Python пытается смягчить эту проблему, представляя то, что известно как Тип намекания (Тип аннотации) Чтобы помочь проверению внешних типов определить любые ошибки. Это хороший способ для программиста, чтобы подсказать тип используемого объекта (ы), во время самого времени компиляции и убедитесь, что шашки типа работают правильно.
Это делает Python Code гораздо более читаемым и надежным, другим читателям!
Примечание : Это делает не Делайте фактическую проверку типа во время компиляции. Если фактический объект возвращен, не был того же типа, что и намекало, будет нет Ошибка компиляции. Вот почему мы используем проверки внешнего типа, такие как Marpy определить любые ошибки типа.
Рекомендуемые предпосылки
Для использования Набрав
Модуль эффективно, рекомендуется использовать проверку/Linter внешний тип для проверки сопоставления статического типа. Один из наиболее широко используемых шахров типа используется для Python, это Marpy Поэтому я рекомендую установить его перед чтением остальной части статьи.
Мы уже охватывали основы проверки типа в Python. Вы можете пройти эту статью первым.
Мы будем использовать Marpy
В качестве проверки статического типа в этой статье, которые могут быть установлены:
pip3 install mypy
Вы можете запустить Marpy
в любой файл Python, чтобы проверить, соответствует ли типы. Это как если бы вы «компилируете» код Python.
mypy program.py
После отладки ошибок вы можете запустить программу, как правило, используя:
python program.py
Теперь, когда у нас наши предпосылки покрыты, давайте попробуем использовать некоторые функции модуля.
Тип подсказки/типа аннотации
На функциях
Мы можем аннотировать функцию, чтобы указать его тип возврата и типы его параметров.
def print_list(a: list) -> None: print(a)
Это информирует проверку типа ( mary
в моем случае), что у нас есть функция print_list ()
это займет Список
как аргумент и возврат Нет
Отказ
def print_list(a: list) -> None: print(a) print_list([1, 2, 3]) print_list(1)
Давайте запустим это на нашем типе Checker Marpy
первый:
vijay@JournalDev:~ $ mypy printlist.py printlist.py:5: error: Argument 1 to "print_list" has incompatible type "int"; expected "List[Any]" Found 1 error in 1 file (checked 1 source file)
Как и ожидалось, мы получаем ошибку; Так как линия № 5 имеет аргумент как int
а не Список
Отказ
На переменных
Поскольку Python 3.6, мы также можем аннотировать типы переменных, упомянув тип. Но это не обязательно, если вы хотите, чтобы тип переменной изменился до возврата функции.
# Annotates 'radius' to be a float radius: float = 1.5 # We can annotate a variable without assigning a value! sample: int # Annotates 'area' to return a float def area(r: float) -> float: return 3.1415 * r * r print(area(radius)) # Print all annotations of the function using # the '__annotations__' dictionary print('Dictionary of Annotations for area():', area.__annotations__)
Выход Mypy :
vijay@JournalDev: ~ $ mypy find_area.py && python find_area.py Success: no issues found in 1 source file 7.068375 Dictionary of Annotations for area(): {'r':, 'return': }
Это рекомендуемый способ использования Marpy
, сначала предоставляя аннотации типа, прежде чем использовать проверку типа.
Тип псевдонимов
Набрав
Модуль дает нам Тип псевдонимов , который определяется путем назначения типа псевдонима.
from typing import List # Vector is a list of float values Vector = List[float] def scale(scalar: float, vector: Vector) -> Vector: return [scalar * num for num in vector] a = scale(scalar=2.0, vector=[1.0, 2.0, 3.0]) print(a)
Выход
vijay@JournalDev: ~ $ mypy vector_scale.py && python vector_scale.py Success: no issues found in 1 source file [2.0, 4.0, 6.0]
На вышеупомянутом фрагменте Вектор
является псевдоним, который обозначает список значений с плавающей запятой. Мы можем ввести намек на псевдоним, что делает то, что делает вышеуказанная программа.
Полный список приемлемых псевдонимов дан здесь Отказ
Давайте посмотрим на еще один пример, который проверяет каждый Ключ: значение Пара в словаре и проверьте, соответствуют ли они Имя: Email формат.
from typing import Dict import re # Create an alias called 'ContactDict' ContactDict = Dict[str, str] def check_if_valid(contacts: ContactDict) -> bool: for name, email in contacts.items(): # Check if name and email are strings if (not isinstance(name, str)) or (not isinstance(email, str)): return False # Check for email xxx@yyy.zzz if not re.match(r"[a-zA-Z0-9\._\+-]+@[a-zA-Z0-9\._-]+\.[a-zA-Z]+$", email): return False return True print(check_if_valid({'vijay': 'vijay@sample.com'})) print(check_if_valid({'vijay': 'vijay@sample.com', 123: 'wrong@name.com'}))
Выход из Mypy.
vijay@JournalDev:~ $ mypy validcontacts.py validcontacts.py:19: error: Dict entry 1 has incompatible type "int": "str"; expected "str": "str" Found 1 error in 1 file (checked 1 source file)
Здесь мы получаем статическую погрешность времени компиляции в Marpy
, так как Имя
Параметр на нашем втором словаре – это целое число ( 123 ). Таким образом, псевдонимы являются еще одним способом обеспечения точной проверки типа «|». Marpy Отказ
Создание пользовательских заданных данных с использованием NewType ()
Мы можем использовать Newtype ()
Функция для создания новых пользовательских типов.
from typing import NewType # Create a new user type called 'StudentID' that consists of # an integer StudentID = NewType('StudentID', int) sample_id = StudentID(100)
Проверка статического типа будет относиться к новому типу, как если бы это был подкласс исходного типа. Это полезно при помощи логических ошибок.
from typing import NewType # Create a new user type called 'StudentID' StudentID = NewType('StudentID', int) def get_student_name(stud_id: StudentID) -> str: return str(input(f'Enter username for ID #{stud_id}:\n')) stud_a = get_student_name(StudentID(100)) print(stud_a) # This is incorrect!! stud_b = get_student_name(-1) print(stud_b)
Выход от Mypy
vijay@JournalDev:~ $ mypy studentnames.py studentnames.py:13: error: Argument 1 to "get_student_name" has incompatible type "int"; expected "StudentID" Found 1 error in 1 file (checked 1 source file)
Любой тип
Это специальный тип, информируя проверку статического типа ( MAPY
В моем случае), что каждый тип совместим с этим ключевым словом.
Рассмотрим наши старые print_list ()
Функция, теперь принимающая аргументы любого типа.
from typing import Any def print_list(a: Any) -> None: print(a) print_list([1, 2, 3]) print_list(1)
Теперь не будет ошибок, когда мы запустим Marpy
Отказ
vijay@JournalDev:~ $ mypy printlist.py && python printlist.py Success: no issues found in 1 source file [1, 2, 3] 1
Все функции без типов возврата или типов параметров будут неявно, по умолчанию использовать Любой
Отказ
def foo(bar): return bar # A static type checker will treat the above # as having the same signature as: def foo(bar: Any) -> Any: return bar
Вы можете использовать Любой смешивать статически и динамически напечатанный код.
Заключение
В этой статье мы узнали о Python Набрав Модуль, который очень полезен в контексте проверки типа, позволяющий шашками внешнего типа, как Marpy
Чтобы точно сообщить о любых ошибках.
Это дает нам способ написать статически напечатанный код в Python, который является динамически наведенным языком по дизайну!
Рекомендации
- Документация Python для модуля набора текста (Это содержит широкие детали на более подробных методах в этом модуле, и я рекомендую это как вторичную ссылку)
- Stackoverflow Вопрос на Type Hints (Это обеспечивает очень хорошее обсуждение по теме. Я настоятельно рекомендую вам прочитать эту тему, а также!)