1 ноября 2026 года Марк Мюллер (Marc Mueller) снова вынес на обсуждение два черновика: PEP 823 и PEP 824. Оба нацелены на Python 3.16, спонсор обоих Гвидо ван Россум, и оба про одно и то же: как короче и надёжнее работать со значениями, которые могут оказаться None.
Если вы пишете на Python бэкенд, скрипты для админки или разбираете JSON из чужих API, то знаете эти лесенки из if x is not None. В других языках их давно заменяют операторы ?. и ??: они есть в TypeScript, JavaScript, C#, Kotlin, Swift, Dart и PHP. Теперь их снова предлагают для Python, на этот раз двумя отдельными документами.
PEP 823: обращение к атрибуту, которое не падает на None
Первый документ добавляет два оператора: ?. для обращения к атрибуту и ?[ ] для обращения по индексу или ключу. Логика простая: Python вычисляет то, что стоит слева, и если там None, вся остальная цепочка пропускается и результатом становится None. Если слева обычный объект, всё работает как с привычной точкой или квадратными скобками.
Пример из самого PEP. Сейчас, чтобы достать имя покупателя, у которого может не быть ни карточки клиента, ни пользователя, пишут так:
def get_customer_name(data):
customer = data.customer
if customer is not None:
user = customer.user
if user is not None:
return user.name.lower()
return None
С новым оператором это одна строка:
def get_customer_name(data):
return data.customer?.user?.name.lower()
Для разбора JSON пригодится вариант со скобками: data.get("customer")?["user"]?["name"]. Как только где-то в цепочке встретится None, всё выражение вернёт None, а не упадёт с TypeError.
Важно понимать, чего эти операторы не делают. Они реагируют только на None и не прячут другие ошибки. Если атрибута нет вовсе, вы всё равно получите AttributeError, а если в словаре нет ключа, то KeyError. Для отсутствующих ключей по-прежнему нужен dict.get(). Присваивать через них нельзя: a?.b = 1 даст SyntaxError. И скобки обрывают цепочку: a?.b.c вернёт None, а (a?.b).c упадёт, если a равно None.
PEP 824: значение по умолчанию вместо None
Второй документ предлагает оператор ?? и его вариант с присваиванием ??=. Запись a ?? b возвращает a, если оно не None, и b в противном случае. Запись a ??= b присваивает значение, только если в a сейчас None.
Главное отличие от привычного or в том, что or заменяет любое «ложное» значение: ноль, пустую строку, пустой список. Из-за этого age = user_age or "unknown" превратит возраст 0 в «unknown». Оператор ?? смотрит только на None, поэтому ноль и пустая строка останутся как есть.
def show_user_age(user):
age = user.age ?? "unknown"
print(f"The user age is {age}")
def add_default_user(users=None):
users ??= []
users.append(create_default_user())
return users
Второй пример закрывает старую проблему с изменяемыми значениями по умолчанию в аргументах функций: вместо трёх строк с if users is None остаётся одна. Приоритет у ?? ниже, чем у or и and, так что a ?? b or c читается как a ?? (b or c). Автор сам советует ставить скобки, когда эти операторы смешиваются в одном выражении.
Почему это обсуждают уже десять лет
Идея не новая. Все четыре оператора предлагал ещё PEP 505 в 2015 году, но его отложили. Новые документы делят идею пополам, и каждый можно принять независимо от другого. Как пишет Real Python, в обсуждениях на discuss.python.org набралось почти двести сообщений, и мнения разделились. Сторонникам ?? нравится, что он реагирует только на None. Пол Мур (Paul Moore), давний мейнтейнер pip, написал, что поведение ?. для него не очевидно, а часть участников считает такие операторы не в духе Python.
Сами PEP разбирают эти возражения отдельно: что знак вопроса легко не заметить в длинной строке, что такие операторы поощряют злоупотребление None, что можно обойтись match, try или библиотекой вроде glom. Автор PEP 823 прямо пишет, что больше одного ?. в цепочке нужно редко, и если их много, стоит подумать о структуре данных или вспомогательной функции.
По графику Python 3.16 новые возможности можно добавлять до первой беты 4 мая 2027 года, финальный релиз запланирован на 5 октября 2027 года. Вторая альфа выйдет 10 ноября. Пока оба документа в статусе черновика, решения Руководящего совета (Steering Council) нет.
Как попробовать операторы уже сейчас
Для обоих PEP есть эталонная реализация в форке CPython и онлайн-демо. Это сборка Python на WebAssembly прямо в браузере: можно написать код в редакторе или открыть интерактивную консоль и проверить, как ведут себя ?., ?[ ], ?? и ??=. В обычных версиях Python, включая альфу 3.16, такой код пока даёт SyntaxError.
Если операторы примут, код, который вытаскивает данные из вложенных объектов и ответов API, станет заметно короче, а ошибки с нулём и пустой строкой, которые сейчас тихо съедает or, станет проще избежать. Если у вас есть мнение, сейчас самое время высказать его в обсуждении: решение по Python 3.16 ещё не принято.

