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

Гид подсказки типа Python: тип намекания в Python

Для науки о данных – и для данных ученый-тип подсказки бесцензируется на пару причин .. Помечено наукой данных, Python, учебником, качеством кода.

Поскольку версии 3.5, Python поддерживает подсказки типа: аннотации кода, которые, через дополнительную оснастку, можно проверить, правильно ли вы используете свой код.

Введение

С выпуском версии 3.5 python представил подсказки типа: аннотации кода, которые, через дополнительную оснастку, можно проверить, правильно ли вы используете свой код.

Дополнительные пользователи Python могут съежиться с мыслью о новом коде, нуждающемся в том, чтобы подсказриваться правильно работать, но нам не нужно беспокоиться: сам Гвидо писал в Pep 484, «Проверка типа не происходит во время выполнения».

Функция была предложена в основном для открытия кода Python для более легкого статического анализа и рефакторинга.

Для науки о данных – и для данного ученого-типа подсказка неоценимо по нескольким причинам:

  • Это делает гораздо легче понять код, просто глядя на подпись, то есть первая строка (ы) определения функции;

  • Он создает слой документации, который можно проверить с помощью проверки типа, то есть. Если вы измените реализацию, но забудьте изменить типы, тип проверки типа (надеюсь) yell на вас.

Конечно, как всегда в случае с документацией и тестированием, это инвестиции: это стоит вам больше времени в начале, но экономит вас (и ваш сотрудник) много в долгосрочной перспективе.

Примечание. Тип намекает также был портирован в Python 2.7 (A.k.a Legacy Python). Функциональность, однако, требует комментариев для работы. Кроме того, никто не должен использовать Legacy Python в 2019 году: это менее красиво, и имеет еще пару больше месяцев обновлений, прежде чем он останавливается при получении поддержки любого рода.

Начало работы с типами

Кодекс для этой статьи можно найти в Репозиторий GitHub Kite Отказ

Hello World of Type намекает:

# hello_world.py
def hello_world(name: str = 'Joe') -> str:
    print(f'Hello {name}')

Мы добавили два типа подсказки здесь. Первый – : ул ...| После имени и второй - -> Ул. к концу подписи.

Синтаксис работает, как вы ожидаете: мы отмечаем имя, чтобы быть типа ул И мы указываем, что hello_world Функция должна выводить ул . Если мы используем нашу функцию, это делает то, что он говорит:

> hello_world(name='Mark')
'Hello Mark'

Поскольку Python остается динамически незанятым языком, мы все еще можем снимать себя в ноге:

> hello_world(name=2)
'Hello 2'

Что творится? Ну, как я писал во вступлении, проверка типа не происходит во время выполнения.

Поэтому до тех пор, пока код не повышает исключение, все будет продолжать работать нормально.

Что вы должны сделать с этими определениями типа? Ну, вам нужен проверка типа, или IDE, которая читает и проверяет типы в свой код (например, Pycharm).

Тип Проверка вашей программы Есть как минимум четыре основных реализация проверки типа Checker: Marpy , Пирас , Пир и Pytype :

  • Marpy Активно разработано, среди прочего, Guido Van Rossum, создатель Python.
  • Пирас был разработан Microsoft и очень хорошо интегрируется со своим превосходным кодом Visual Studio;
  • Пир был разработан Facebook с целью быть быстрой (даже если Mypy недавно получил намного быстрее);
  • Pytype Был разработан Google и, помимо проверки типов, поскольку другие делают, он может запускать проверки типа (и добавлять аннотации) на неннотационный код. Поскольку мы хотим сосредоточиться на том, как использовать печатать на перспективе Python, мы будем использовать MAPY в этом руководстве. Мы можем установить его, используя Пип (или ваш пакет менеджер по выбору):
$ pip install mypy
$ mypy hello_world.py 

Более продвинутые типы В принципе, все классы Python являются действительными типами, что означает, что вы можете использовать ул ...| С int , плавать , так далее. Использование словаря, кортежи и аналогии также возможна, но вам нужно импортировать их из модуля печати.

# tree.py
from typing import Tuple, Iterable, Dict, List, DefaultDict
from collections import defaultdict

def create_tree(tuples: Iterable[Tuple[int, int]]) -> DefaultDict[int, List[int]]:
    """
    Return a tree given tuples of (child, father)

    The tree structure is as follows:

        tree = {node_1: [node_2, node_3], 
                node_2: [node_4, node_5, node_6],
                node_6: [node_7, node_8]}
    """
    tree = defaultdict(list) 
    for child, father in tuples:
        if father:
            tree[father].append(child)
    return tree

print(create_tree([(2.0,1.0), (3.0,1.0), (4.0,3.0), (1.0,6.0)]))
# will print
# defaultdict( 'list'="">, {1.0: [2.0, 3.0], 3.0: [4.0], 6.0: [1.0]}

Пока код прост, он представляет пару дополнительных элементов:

Прежде всего, Потенциал Тип для кортежи Переменная. Этот тип указывает, что объект должен соответствовать коллекции .abc. Потенциал Спецификация (т.е. реализует __er____ ). Это необходимо, потому что мы повторяем кортежи в цикле; Мы указываем типы внутри наших объектов контейнера: ITERABLE содержит корки, кортежи состоят из пар int , и так далее.

Хорошо, давайте попробуем напечатать его!

$ mypy tree.py
tree.py:14: error: Need type annotation for 'tree'

Э-э, что происходит? В основном Mypy жалуется на эту строку:

tree = defaultdict(list)

Хотя мы знаем, что тип возврата должен быть Defaultdict [int, список [int]] Mypy не может сделать вывод, что дерево действительно такого типа. Нам нужно помочь ему, указав тип дерева. Это может быть сделано так же, как мы делаем это в подписи:

tree: DefaultDict[int, List[int]] = defaultdict(list)

Если мы сейчас снова запускаем Mypy, все хорошо:

$ mypy tree.py
$

Тип псевдонимов

Иногда наш код использует одни и те же композитные типы снова и снова. В приведенном выше примере кортеж [int, int] может быть таким случаем. Чтобы сделать наш намерение более четко (и сократить наш код), мы можем использовать псевдонимы типа. Псения типа очень просты в использовании: мы просто назначаем тип переменной и использовать эту переменную в качестве нового типа …

Relation = Tuple[int, int]

def create_tree(tuples: Iterable[Relation]) -> DefaultDict[int, List[int]]:
    """
    Return a tree given tuples of (child, father)

    The tree structure is as follow:

        tree = {node_1: [node_2, node_3], 
                node_2: [node_4, node_5, node_6],
                node_6: [node_7, node_8]}
    """
    # convert to dict
    tree: DefaultDict[int, List[int]] = defaultdict(list) 
    for child, father in tuples:
        if father:
            tree[father].append(child)

    return tree

Универсал

Опытные программисты статически напечатанных языков, возможно, заметили, что определение отношения в виде кортежа целых чисел, немного ограничивает. Не может create_tree Работайте с поплавкам или строкой, или класс Ad-Hoc, который мы только что создали?

В принципе, нет ничего, что мешает нам использовать это так:

# tree.py
from typing import Tuple, Iterable, Dict, List, DefaultDict
from collections import defaultdict

Relation = Tuple[int, int]

def create_tree(tuples: Iterable[Relation]) -> DefaultDict[int, List[int]]:
    ...

print(create_tree([(2.0,1.0), (3.0,1.0), (4.0,3.0), (1.0,6.0)]))
# will print
# defaultdict( 'list'="">, {1.0: [2.0, 3.0], 3.0: [4.0], 6.0: [1.0]})

Однако, если мы спросим мнение Mypy о коде, мы получим ошибку:

$ mypy tree.py
tree.py:24: error: List item 0 has incompatible type 'Tuple[float, float]'; expected 'Tuple[int, int]'
...

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

Проверьте код – Руководство: Тип намекания в Python 3.5 в блоге kite. Джованни Ланзани является директором обучения и развития в Годадривенном.

Оригинал: “https://dev.to/kite/guide-type-hinting-in-python-1p1l”