Рубрики
Без рубрики

Модуль набора Python – эффективно использовать шашки типа

Введено с момента Python 3.5, модуль набора текста Python пытается обеспечить способ намерения, чтобы помочь шашкам типа статических типов, а линтам точно прогнозировать

Автор оригинала: 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, который является динамически наведенным языком по дизайну!

Рекомендации