Программы
Новое в Python 3.8: строго-позиционные (position-only) параметры функций

Новое в Python 3.8: строго-позиционные (position-only) параметры функций

Очередное синтаксическое новшество, которое нам представит Python 3.8 - параметры функций, которые можно будет использовать только позиционно.

В дополнении к "моржовому оператору" в Python 3.8 появится ещё один специальный символ для описания параметров функции. Если до этого мы имели дело со звёздочкой (*), то теперь ещё получим косую черту/слеш (/).

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

def get_statistic(stat_data, *, user, date_from=None, date_to=None):
    """Получение статистики по пользователю с фильтром по дате"""

Таким образом мы обязаны передать параметр stat_data (данные для фильтрации), а также передать юзера как именованный аргумент. Остальные – также указываются как именованные аргументы, но являются необязательными:

>>> get_statistic([], user='user_login')
>>> get_statistic([], user='user_login', date_from='2019-05-01')
>>> get_statistic([], 'user_login')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: get_statistic() takes 1 positional argument but 2 were given

– довольно полезно и наглядно, когда параметров много. Например, для указания параметров фильтрации, где потенциально их может быть очень много.

Аналогично работает /. Однако, все параметры, которые шли до него, обязаны быть позиционными. То есть, если мы опишем функцию:

def contains(collection, key, /):
    """Поиск элемента в коллекции"""

– то мы не сможем вызвать эту функцию как contains([1, 2, 3], key=2), а только contains([1, 2, 3], 2). К слову, посмотрите, как описан метод __contains__ объекта range уже сейчас:

>>> help(range)

Help on class range in module builtins:

class range(object)
 |  range(stop) -> range object
...
 |  __contains__(self, key, /)
 |      Return key in self.
...

Такой синтаксис уже давно используется для Python-функций, написанных на Си. Теперь так можно будет писать прямо в Python (на момент 3.8.0a3 уже есть такая возможность).

PEP по этой новой синтаксической возможности довольно интересен. Особенно часть "Rejected Ideas". Однако, сейчас хочется больше рассмотреть раздел с мотивацией.

Помимо более жёсткого прибивания гвоздями вариантов вызова функций... и консистентности языка в плане "как в хелпе сишных функций"... Пожалуй, логичным выглядит довод с параметрами, которые имеют смысл как последовательность. Например,

range(stop=5, start=0, step=2)
range(stop=5, step=2, start=0)
range(step=2, start=0, stop=5)
range(step=2, stop=5, start=0)

– и да, range не примет и так позиционные аргументы, но порядок старт-финиш-шаг привычен. Изменение его (если бы это можно было сделать) могло бы запутать. Правда, таких "злобных буратин" надо ещё поискать... Тем не менее, это уже имеет определённый смысл. Ожидаем в Python 3.8!

И всё же, молю пользоваться новыми возможностями с осторожностью: не у всякого выдержит психика подобный код:

def name(
    positional_only_parameters,
    /,
    positional_or_keyword_parameters,
    *,
    keyword_only_parameters
):

А если ещё без форматирования, да с type-hinting-ом, да дефолтными значениями...

Также может быть вам интересно:

Интервью с Артёмом Кузвесовым. Про конференции и как на них выступать

Про конференции и выступления на них сегодня нам расскажет докладчик многих конференций - Артём Кузвесов

Читать »

Интервью с Артёмом Кузвесовым. Часть 2-ая

О том, как выбрать доклад, на какую конференцию ехать и с чего стоит начать докладчику.

Читать »
Фото Как настроить отправку почты из Django

Как настроить отправку почты из Django

Письма об ошибках, отчёты на почту, восстановление паролей - всё это полезно при работе с сайтом. Django предоставляет удобный способ это сделать с минимумом настроек!

Фото Добавляем поддержку медиа-файлов в Django проект

Добавляем поддержку медиа-файлов в Django проект

Современные сайты редко ограничиваются только текстом и вёрсткой. Часто в заметках красуются фотографии, а рядом с описанием товаров - их изображения.

Фото Настройка журналирования (логирования) в Python с примерами

Настройка журналирования (логирования) в Python с примерами

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

Фото Маленькая книга о Go (golang)

Маленькая книга о Go (golang)

Маленькая книга о Go распространяется под лицензией Attribution-NonCommercial-ShareAlike 4.0 International license. Вы не должны платить за эту книгу.

Фото Пример своей консольной команды в Django проекте

Пример своей консольной команды в Django проекте

Если вы работали с Django проектом, то, скорее всего, запускали команды из консоли (manage.py). В Django есть простой способ писать свои команды для управления проектом.

Фото Разграничение прав доступа на Django сайте

Разграничение прав доступа на Django сайте

Почти на любом веб-сайте необходимо разделять пользователей на группы и предоставлять им разные возможности. В Django есть довольно серьёзная система прав доступа для пользователей - давайте её рассмотрим!

Фото Пользователи и их создание в Django - своя регистрация на сайте

Пользователи и их создание в Django - своя регистрация на сайте

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

Фото Как на Bash посчитать число строк в проекте (директории)

Как на Bash посчитать число строк в проекте (директории)

Ниже будет представлен однострочник, решающий данную задачу на Bash + пошаговое описание его работы.