Программы
Новое в 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-ая

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

Читать »
Фото Python: Встроенные типы данных (list, set, dict, etc)

Python: Встроенные типы данных (list, set, dict, etc)

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

Фото Python: типы данных, переменные, логическое ветвление и циклы

Python: типы данных, переменные, логическое ветвление и циклы

Первая часть заметок о Python. О базовых типах, переменных, ветвлении и циклах.

Фото Как сделать свою middleware в Django (с примерами)

Как сделать свою middleware в Django (с примерами)

Middleware или "промежуточное программное обеспечение" - элегантный способ установить общие правила обработки запросов и ответов приложения. Давайте напишем парочку middleware, чтобы понять, как они работают.

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

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

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

Фото Новый оператор match-case в Python

Новый оператор match-case в Python

В новой версии Python (3.10) появится новый оператор. Новый оператор сопоставления по шаблону (match-case).

Фото Нет слов, одни... однострочники

Нет слов, одни... однострочники

На днях вышел пост со списком полезных однострочников для JavaScript программистов. Памятуя Perl-овую молодость, заглянул туда.

Фото Добавляем переменные в контекст Django шаблонов (свой контекст-процессор)

Добавляем переменные в контекст Django шаблонов (свой контекст-процессор)

В Django вы можете передавать данные в шаблоны посредством контекстов. Контекст передаётся из контроллера (view в терминах Django), однако, если одни и те же данные нужны в разных местах, лучше сделать свой контекст-процессор.

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

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

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