Python 3.10 - пять новых функций и соображений

Не только перечисление, но также примеры и соображения.

Несколько дней назад наконец-то был выпущен Python 3.10. В Интернете уже есть много статей, которые были опубликованы еще до того, как он был выпущен. Однако я обнаружил, что большинство из них просто перечисляют новые функции без особого обсуждения. Поэтому в своей статье я постараюсь привести несколько примеров того, как использовать эти новые функции. Кроме того, я буду обсуждать их со своим личным мнением.

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



Вместо того, чтобы просто сосредоточиться на функциях, я также подскажу, как получить эту новую версию Python, чтобы мы все могли начать экспериментировать. Поскольку он уже выпущен, я могу использовать свой любимый набор инструментов для управления средами Python - Anaconda, чтобы загрузить его. Если у вас его еще нет, его можно скачать бесплатно.



После установки мы можем создать новую виртуальную среду Python с новейшей версией - 3.10.

conda create --name py310 python=3.10

Поздравляю! Установлен последний Python.

1. Разрешить запись типов объединения как X | Y

Первая важная особенность - это синтаксис типов объединения. В частности, мы можем использовать канал между двумя или более типами для представления «либо этого типа, либо этого типа».

Чаще всего этот синтаксис используется для проверки типа объекта. Вместо того, чтобы писать несколько условий, таких как isinstance(x, int) or isinstance(x, str), теперь мы можем написать следующий код.

isinstance(x, int | str)

См. Пример ниже.

Первое, что приходит мне в голову, это то, что мы можем использовать этот синтаксис для написания некоторых надежных условий. Например, переменная должна быть целым числом, но также может иметь значение «Нет», что тоже верно, тогда мы можем написать такое условие.

isinstance(x, int | None)

В дополнение к этому подпись функции. Теперь мы можем использовать этот синтаксис, чтобы указать, что параметр может быть нескольких типов. Например, мы хотим написать такую ​​функцию, чтобы добавить 1 к переданному в нее аргументу. Аргумент может быть целым числом или строкой, а возвращаемое значение должно быть таким же, как исходный тип.

def plus_1(number: int | str):
    if isinstance(number, int):
        return number + 1
    else:
        number = int(number)
        return str(number + 1)

Мы можем проверить, работает ли он должным образом.

2. Добавьте опциональную проверку длины в застежку-молнию ()

Функция zip() подробно обсуждалась в одной из моих предыдущих статей. Эта новая функция в Python 3.10 также упоминалась здесь. Это очень мощная и полезная функция в Python. Настоятельно рекомендуется прочитать мою статью, если вы не слишком разбираетесь в ней.



« Закрепите объекты Python с помощью Zip
Уловка Python упрощает использование нескольких итераций в сторону datascience.com»



Вкратце, функция zip() будет получать элементы из двух контейнеров (таких как список) один за другим и помещать элементы в соответствующие позиции в обоих контейнерах вместе в кортеж. Взгляните на пример ниже.

list(
    zip([1, 2, 3], ['a', 'b', 'c'])
)

По умолчанию, если мы предоставили два списка разной длины, лишние элементы в более длинном будут проигнорированы. Это также известно как «эффекты ведра».

list(
    zip([1, 2, 3], ['a', 'b', 'c', 'd'])
)

В приведенном выше примере элемент 'd' во втором списке был проигнорирован.

Однако иногда мы можем не знать, что есть элементы, которые игнорируются, потому что функция будет делать это незаметно. Поэтому в Python 3.10 введен новый флаг под названием «strict», чтобы заставить два списка иметь одинаковую длину.

list(
    zip([1, 2, 3], ['a', 'b', 'c', 'd'], strict=True)
)

Если мы явно зададим strict=True, будет выдано исключение, если длины будут разными.

3. Заключение в скобки контекстных менеджеров теперь официально разрешено.

В предыдущих версиях наличие нескольких предложений в одном операторе «with» было немного болезненным. Например, если мы хотим открыть два файла в одном операторе «with», мы должны записать их в одной строке.

with open('sample_data/mnist_test.csv') as test, open('sample_data/mnist_train_small.csv') as train:
    pass

В блокноте это выглядит так.

Это будет очень болезненно, когда у нас очень длинные аргументы в функции open().

Есть решение улучшить наш код - добавить обратную косую черту, чтобы мы могли разбить их на несколько строк.

with open('sample_data/mnist_test.csv') as test, \
     open('sample_data/mnist_train_small.csv') as train:
    pass

Тогда это выглядит так.

Это определенно лучше, но все же немного некрасиво для этой обратной косой черты.

Теперь, в новой версии, мы можем заключить в круглые скобки, чтобы код был более аккуратным и читабельным.

with (open('1.txt') as first_file,
      open('2.txt') as second_file):

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

with (
    open('1.txt') as first_file,
    open('2.txt') as second_file,
    open('3.txt') as third_file,
    open('4.txt') as fourth_file
):

4. Новый синтаксис: match… case…

Наличие в Python синтаксиса «switch… case…» является довольно спорным. Даже отец Python, Гвидо, не поддерживает добавление такого синтаксиса в Python. Однако он все еще выпущен в этой новой версии, и я действительно был убежден, что этот синтаксис хорош.

Обратите внимание, что люди обычно говорят «поменять регистр», потому что это обычно используется в других языках программирования. Однако в Python используются ключевые слова «match… case…».

Например, мы можем возвращать разные сообщения на основе кода HTTP.

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 401:
            return "Unauthorized"
        case 403:
            return "Forbidden"
        case 404:
            return "Not found"
        case _:
            return "Unknown status code"

В этом примере консервативные разработчики могут по-прежнему утверждать, что на самом деле он не дает никаких преимуществ для улучшения читаемости кода. Мы можем переписать эту функцию, используя if-else, и это неплохо.

def http_error(status):
    if status == 400:
        return "Bad request"
    elif status == 401:
        return "Unauthorized"
    elif status == 403:
        return "Forbidden"
    elif status == 404:
        return "Not found"
    else:
        return "Unknown status code"

В самом деле, для такого общего случая использования синтаксис совпадений не имел большого значения. Однако, на мой взгляд, новое ключевое слово «совпадение» указывает на основную логику и цель этого синтаксиса. Он предназначен для облегчения нашей жизни, когда мы хотим «сопоставить» некоторые шаблоны для выражения.

Например, мы хотим написать функцию для возврата URL-адреса хоста, номера порта и типа протокола из кортежа. Однако в кортеже может быть только два элемента (хост и порт). В этом случае мы хотим вернуть протокол по умолчанию «https». Если кортеж уже предоставил протокол, нам нужно будет его вернуть.

Используя синтаксис if-else, мы должны написать следующий код.

def get_url(info):
    if isinstance(info, tuple) and len(info) == 2:
        host, port = info
        protocol = "http"
    elif isinstance(info, tuple) and len(info) == 3:
        host, port, protocol = info
    
    return host, port, protocol

Это опять же не так уж и плохо. Однако, если мы подумаем о двух шаблонах, которым мы пытаемся сопоставить, мы можем переписать код следующим образом, используя новый синтаксис.

def get_url(info):
    match info:
        case host, port:
            protocol = 'http'
        case host, port, protocol:
            pass
    
    return host, port, protocol

Ух ты! Очень аккуратно и чисто, а читабельность намного лучше, чем у версии if-else. Вот что я думаю о том, как нам следует использовать этот новый синтаксис!

5. Расширенные сообщения об ошибках.

Раньше сообщение об ошибке Python иногда не было идеальным. Например, в приведенном ниже коде отсутствует правая скобка.

my_dict = {'name': 'Chris', 'age': 33

Сообщение об ошибке просто скажет нам, что при синтаксическом анализе кода не удалось.

В новой версии эти сообщения об ошибках значительно улучшены. Он прямо скажет нам, почему не удалось проанализировать код.

Некоторое сообщение об ошибке вызывает у разработчиков чувство тепла: D

Резюме

В этой статье я представил 5 наиболее важных новых функций Python 3.10, выпущенных несколько дней назад. Надеюсь, это будет полезно и хорошо продемонстрирует эти новые функции на приведенных мною примерах.



Если вы считаете, что мои статьи полезны, рассмотрите возможность присоединения к Medium Membership, чтобы поддержать меня и тысячи других авторов! (Щелкните ссылку выше)