Что нового в Python 3.6?

С момента выпуска версии 3.5 прошло более года. В статье — краткий обзор наиболее интересных изменений, которые затронули Python 3.6, с примерами.

PEP 468: сохранение порядка именных аргументов

def pep468(**kwargs):
    print(list(kwargs.keys()))

>>> pep468(a=1, b=2, c=3)
['a', 'b', 'c']

PEP 487: упрощенная кастомизация процесса создания классов

class PEP487:
    def __init_subclass__(cls, whom, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.hello = lambda: print(f"Hello, {whom}")

>>> class HelloWorld(PEP487, whom="World"):
... pass

>>> HelloWorld.hello()
Hello, World

PEP 495: устранение неоднозначности в локальном времени

dt = datetime.datetime(2016, 11, 6, 1, 30)
pdt = dt.astimezone()
pst = dt.replace(fold=1).astimezone()

>>> pdt.strftime('%Y-%m-%d %T %Z%z')
'2016-11-06 01:30:00 Pacific Summer Time-0700'
>>> pst.strftime('%Y-%m-%d %T %Z%z')
'2016-11-06 01:30:00 Pacific Standard Time-0800'

PEP 498: форматированные строковые литералы

>>> whom = "PyCon CA"
>>> where = "Toronto", "ON", "Canada"
>>> f"Hello, {whom}! Welcome to {where!r}."
"Hello, PyCon CA! Welcome to ('Toronto', 'ON', 'Canada')."

PEP 506/524: модуль secrets и блоки os.urandom()

PEP 506

  • Используйте модуль secrets для задач, связанных с безопасностью или криптосвязью.
  • Используйте random для задач моделирования и симуляции.

PEP 524

  • В Python 3.5.0 os.urandom() блокируется до тех пор, пока недостаточно энтропии.
  • В Python 3.5.2 os.urandom() вернется к /dev/urandom, если произойдет блокирующий вызов (это плохо, если нужны криптографически стойкие биты).
  • В Python 3.6 os.urandom() возвращается к семантике 3.5.0.
  • Новый os.getrandom() вызывает исключение, если происходит блокировка.

PEP 509: словарь получил private-версию

  • 99,9% разработчиков об этом не заботятся (напрямую).
  • Словари теперь имеют идентификатор версии, доступный только из кода C:
    • можете рассматривать это как индикатор того, что пространства имен изменились;
    • полезно для кэширования, например, в запросах к глобальному и встроенному пространству имен.

PEP 515: знаки подчеркивания в числовых литералах

one_billion = 1_000_000_000
black = 0x_FF_FF_FF_FF

PEP 519: добавлен протокол пути файловой системы

os.path.exists(pathlib.Path("Что нового в Python 3.6.pptx"))

class Pathy(os.PathLike):
    def __fspath__(self) -> Union[str, bytes]:
        return path_repr

PEP 520: сохранение порядка определения атрибутов класса

class OrderPreserved:
    a = 1
    b = 2
    def meth(self):
        pass


>>> list(OrderPreserved.__dict__.keys())
['__module__', 'a', 'b', 'meth', '__dict__', '__weakref__', '__doc__']

PEP 523: добавлен API для определения качества кадров в CPython

  • 99% разработчиков не заботятся об этом (вас это заинтересует, только если вы пишете JIT, отладчик или профилировщик).
  • В настоящее время существует API C, который позволяет указать альтернативную функцию для определения качества кадров (т. е. по существу задействуется PyEval_EvalFrameEx()).

PEP 525/530: асинхронные генераторы и выражения

# для использования внутри `async for`.
async def ticker(delay, to):
    for i in range(to):
        yield i
        await asyncio.sleep(delay)


async def async_comprehensions():
    comp_with_async = [i async for i in aiter() if i % 2]
    comp_with_await = [await fun() for fun in funcs]

PEP 526: синтаксис для аннотирования переменных

module_level: str = "см. __annotations__"
class Annotated:
    ins: int # еще не существует.
    ins_with_default: str = "см. Annotated.__annotations__"
    cls: ClassVar[float] = 3.14

    def meth(self):
        local: int = 42
        does_not_exist_yet: str

PEP 528/529: кодировка по умолчанию в Windows

REPL теперь использует UTF-8! Пути на основе строк байтов теперь допустимы в Windows (sys.getfilesystemencoding() возвращает UTF-8).

Кое-что не из PEP

PYTHONMALLOC: можно включать и отключать хуки для отладки памяти и принудительно использовать malloc() для всех распределений памяти.

Что изменилось в поддержке DTrace/SystemTap?

  • CPython необходимо компилировать с опцией --with-dtrace.
  • Трассировка (вызовы/возвраты функций, запуск/остановка сборщика мусора, строка исполняемого кода).

По материалам Dr. Brett Cannon (Microsoft). См. также официальную документацию.