
Вышел новый релиз Python 3.11, который содержит несколько приятных новых функций и функций. В этом обзоре перечислены наиболее важные изменения, которые помогут вам обновить Python.
Новый релиз содержит улучшения в области исключений и обработки исключений в Python, новый модуль для обработки файлов TOML, улучшения для интерпретатора, новые типы и функции, а также объявляет устаревшими некоторые старые модули и API языка. Кроме того, тесты Python утверждают, что Python 3.11 на 10–60% быстрее, чем Python 3.10: вы можете увидеть результаты здесь.
Как установить и обновить
линукс
В Linux (в данном случае: Ubuntu) вы можете установить и обновить Python через локальный менеджер пакетов. Вы можете использовать deadsnakes PPA для установки самых последних версий Python.
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppaПосле добавления репозитория вы можете установить Python 3.11 через apt:
sudo apt-get update
sudo apt-get install python3.11macOS
В macOS я рекомендую использовать менеджер пакетов homebrew. Вы можете установить доморощенный через:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"После установки homebrew вы можете установить Python 3.11:
brew install [email protected]Или, если вы уже установили более раннюю версию Python через homebrew (и обновили сам менеджер пакетов), обновите пакет Python до версии 3.11 с помощью этой команды:
brew upgrade python -v 3.11Окна
В Windows у вас есть два способа обновить Python: через установщик Python или менеджер пакетов Chocolatey. Вы найдете установщик Python на официальной странице загрузки, и он проведет вас через весь процесс. Если вы хотите использовать менеджер пакетов Chocolatey, вы можете установить его через:
Set-ExecutionPolicy Bypass -Scope Process -Force; \
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))Затем вы можете использовать Chocolatey для установки Python 3.11 через командную строку:
choco install python -y --version 3.11Или вы обновляете Python, если он уже установлен:
choco upgrade python -y --version 3.11Группы исключений, кроме* и примечания
Теперь можно вызывать и обрабатывать несколько несвязанных исключений одновременно.  Недавно введенный тип ExceptionGroup может объединять несвязанные исключения:
exceptions = ExceptionGroup(
    "all",
    [
        TypeError(1),
        ExceptionGroup("ex", [TypeError(2), ValueError(3)]),
        ExceptionGroup("os", [OSError(4)])
    ]
)Эти пакеты дают красивые печатные иерархии:
import traceback traceback.print_exception(exceptions)| ExceptionGroup: all (3 sub-exceptions) +-+---------------- 1 ---------------- | TypeError: 1 +---------------- 2 ---------------- | ExceptionGroup: ex (2 sub-exceptions) +-+---------------- 1 ---------------- | TypeError: 2 +---------------- 2 ---------------- | ValueError: 3 +------------------------------------ +---------------- 3 ---------------- | ExceptionGroup: os (1 sub-exception) +-+---------------- 1 ---------------- | OSError: 4 +------------------------------------
Вы можете использовать условия соответствия для этих групп исключений, создавать их подклассы, создавать собственные обработчики для обработки так называемых листовых исключений и многое другое.
Python 3.11 представляет новое (или расширенное) ключевое слово для упрощения работы с ExceptionsGroups: except*.  Символ * указывает, что можно обрабатывать несколько исключений:
try:
    ...
except* CustomError:
    ...
except* OSError as e:
    ...
except* (TypeError, ValueError) as e:
    ...Описание PEP-0654 предоставляет дополнительную документацию для нового ключевого слова except*, например, рекурсивное сопоставление, вызов исключений в блоке исключений* или цепочка.
Базовый класс исключений BaseException также стал новым методом.  Этот метод был добавлен, поскольку при перехвате и повторном возникновении исключений может быть добавлена дополнительная информация.
add_note(note)
Добавьте строку
noteв примечания к исключению, которые отображаются в стандартной трассировке после строки исключения.TypeErrorвозникает, еслиnoteне является строкой.
Добро пожаловать в новый модуль: tomllib
Tom’s Obvious Minimal Language (TOML) задуман как формат файла конфигурации, который является минимальным и легко читаемым. Синтаксис похож на INI-файлы, но он представляет собой фактический стандарт, в то время как INI имеет множество разновидностей. TOML поддерживает различные типы данных: String, Integer, Float, Boolean, Datetime, Array и Table. Поскольку он состоит из пар ключ-значение, его структура удобно анализируется в виде хэш-карты. Ниже приведен минимальный пример:
# this is a TOML config file exampletitle = "Config"[general] name = "Database" created = 2022-11-26T08:30:00+02:00[database][database.connection] server = "192.168.1.1" ports = [ 8000, 8001, 8002 ][database.auth] username = "root" password = "root"
Теперь Python 3.11 добавляет в стандартную библиотеку модуль для разбора файлов TOML под названием tomllib. К сожалению, на данный момент модуль поддерживает только синтаксический анализ файлов TOML, но не их запись. Предлагаются две альтернативы, если вам нужны возможности записи: пакет Tomli-W и пакет TOML Kit.
Однако, если вам просто нужно прочитать файл TOML, вы можете использовать новый модуль из стандартной библиотеки.  Имейте в виду, что любой файл TOML должен быть открыт в двоичном режиме, чтобы tomllib мог правильно обрабатывать кодировку UTF-8 во всех системах.  В следующем примере показано, как вы могли бы проанализировать наш пример файла TOML из приведенного выше:
import tomllibwith open("config.toml", "rb") as f: config = tomllib.load(f)server = config['database']['connection']['server'] for port in config['database']['connection']['ports']: print(f'{server}:{port}')
Вы можете найти дополнительные советы и рекомендации по работе с модулем tomllib в статье RealPython, например, указав метод float для управления анализом и представлением чисел с плавающей запятой.
Улучшения интерпретатора
Python 3.11 догоняет возможности более современных компиляторов и теперь также будет указывать конкретное выражение, вызвавшее ошибку, а не просто указывать на строку:
Traceback (most recent call last):
  File "distance.py", line 11, in <module>
    print(manhattan_distance(p1, p2))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "distance.py", line 6, in manhattan_distance
    return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
                           ^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'x'Кроме того, есть новый параметр командной строки -P, который вместе с переменной среды с именем PYTHONSAFEPATH отключает автоматическое добавление потенциально небезопасных путей к sys.path.  Это функция, которую можно интегрировать в среду непрерывной интеграции для обеспечения безопасности и переносимости.
-P
Не добавляйте потенциально небезопасный путь к
sys.path:
python -m moduleкомандная строка: не добавляйте текущий рабочий каталог.
python script.pyкомандная строка: не добавляйте каталог сценария. Если это символическая ссылка, разрешите символические ссылки.
Командные строки
python -c codeиpython(REPL): не добавляйте пустую строку, которая означает текущий рабочий каталог.
См. также переменную окружения
PYTHONSAFEPATHи параметры-Eи-I(изолированные).
Дополнительные типы и особенности типов
В новой версии представлены новые функции набора текста. Они кратко показаны в следующих разделах.
Вариативные дженерики
В Python 3.5 уже появилось TypeVar для дженериков, параметризованных одним типом.  В Python 3.11 появился TypeVarTuple, который позволяет параметризовать произвольное количество типов.  Следующий пример взят из PEP-646 и показывает использование этой новой функции:
from typing import TypeVar, TypeVarTupleDType = TypeVar('DType') Shape = TypeVarTuple('Shape')class Array(Generic[DType, *Shape]):def __abs__(self) -> Array[DType, *Shape]: ... def __add__(self, other: Array[DType, *Shape]) -> Array[DType, *Shape]: ...from typing import NewTypeHeight = NewType('Height', int) Width = NewType('Width', int)x: Array[float, Height, Width] = Array()
Пометка отдельных элементов TypedDict как обязательных или необязательных
Теперь отдельные элементы в TypedDict могут быть отмечены, должны ли они присутствовать или нет.  По умолчанию все поля по-прежнему обязательны для обратной совместимости.  Однако есть также параметр total, для которого можно установить значение False: в этом случае все поля TypedDict по умолчанию не обязательны.
class Movie(TypedDict): title: str year: NotRequired[int]m1: Movie = {"title": "Black Panther", "year": 2018} # OK m2: Movie = {"title": "Star Wars"} # OK (year is not required) m3: Movie = {"year": 2022} # ERROR (missing required field title)
Собственный тип
PEP-673 вводит аннотацию Self для методов, которые возвращают экземпляр своего класса.  В следующем примере показан вариант использования альтернативного конструктора:
class MyInt:
    @classmethod
    def fromhex(cls, s: str) -> Self:
        return cls(int(s, 16))Произвольный литеральный строковый тип
Python 3.11 представляет новую аннотацию для дополнительной безопасности в отношении строк: LiteralString.  Эта аннотация позволяет функциям принимать произвольные типы литеральных строк, а также строки, созданные из других литеральных строк.  Вы можете установить требования к конфиденциальным функциям, например тем, которые выполняют операторы SQL для защиты от атак путем внедрения кода SQL.
В соответствии с PEP-675 показано, как эту аннотацию можно использовать для SQL-запросов:
def run_query(sql: LiteralString) -> ... ...def caller( arbitrary_string: str, query_string: LiteralString, table_name: LiteralString, ) -> None: run_query("SELECT * FROM students") # ok run_query(query_string) # ok run_query("SELECT * FROM " + table_name) # ok run_query(arbitrary_string) # type checker error run_query( # type checker error f"SELECT * FROM students WHERE name = {arbitrary_string}" )
Старое должно уйти: устаревание
Следующие устаревшие стандартные библиотечные модули объявлены устаревшими и будут удалены в Python 3.13:
- aifc
- chunk
- msilib
- pipes
- telnetlib
- audioop
- crypt
- nis
- sndhdr
- uu
- cgi
- imghdr
- nntplib
- spwd
- xdrlib
- cgitb
- mailcap
- ossaudiodev
- sunau
Кроме того, модули asynchat, asyncore и smtpd (которые уже объявлены устаревшими) были обновлены, чтобы отметить, что они будут удалены в Python 3.12.  Кроме того, пакет lib2to3 и инструмент 2to3 теперь устарели и, возможно, не смогут анализировать Python 3.10 или новее.  Недокументированные модули sre_compile, sre_constants и sre_parse теперь также устарели.
API-интерфейсы кодировщика Py_UNICODE были удалены, потому что они уже устарели и больше не используются, поскольку есть лучшие и более эффективные альтернативы. Если вы все еще используете эти API, соответствующий PEP-624 предоставляет руководство по миграции.
Некоторые макросы были преобразованы в статические встроенные функции, чтобы избежать подводных камней макросов. Вы можете найти дополнительную информацию об этих макросах в соответствующем PEP-670.
Заключение
Новый выпуск Python 3.11 приносит много нового и хорошего: улучшенную производительность, больше возможностей для обработки исключений, новый модуль для разбора файлов TOML, улучшения интерпретатора, дополнительные типы, аннотации и функции типов, а также устаревшие и удаление некоторого старого языкового багажа.
Решите для себя, стоит ли обновляться, но самое главное: продолжайте кодить и продолжайте творить!
 
                                                                     
                                                                    