LINUX.ORG.RU

Python 3.7

 


5

8

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

В этом выпуске

  • Улучшена поддержка аннотации типов
  • Data classes
  • Атрибуты модулей
  • Отладка с помощью breakpoint()
  • И многое другое

PEP 563, Отложенное исполнение аннотаций типов

Теперь аннотации разрешаются в момент вызова функции, а не в момент загрузки её кода. Это уменьшает время старта программы и делает доступным использование имён, определённых позднее самой функции (forward references).

Такой код вызывал бы ошибку в предыдущих версиях Python

class C:
    @classmethod
    def from_string(cls, source: str) -> C:
        ...

    def validate_b(self, obj: B) -> bool:
        ...

class B:
    ...

Это изменение нарушает совместимость, поэтому до прихода версии Python 4.0 пока требует

from __future__ import annotations

PEP 553, Встроенная функция breakpoint()

Отладка стала ещё проще! Допустим, у вас есть такой код

def divide(e, f):
    return f / e

a, b = 0, 1
print(divide(a, b))

В предыдущих версиях для отладки вам требовалось:

def divide(e, f):
    import pdb; pdb.set_trace()
    return f / e

В 3.7 это выглядит проще и короче

def divide(e, f):
    breakpoint()
    return f / e

Теперь запускайте ваш код:

$ python3.7 bugs.py 
> /home/gahjelle/bugs.py(3)divide()
-> return f / e
(Pdb)

По умолчанию breakpoint() просто заменяется на import pdb; pdb.set_trace(), однако это можно изменить. Скажем, вы можете использовать другой отладчик:

$ PYTHONBREAKPOINT=pudb.set_trace python3.7 bugs.py
Или отключить отладку вовсе
$ PYTHONBREAKPOINT=0 python3.7 bugs.py
ZeroDivisionError: division by zero
Или запустить IPython
$ PYTHONBREAKPOINT=IPython.embed python3.7 bugs.py 
IPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: print(e / f)
0.0
В конечном счёте, вы можете написать свой собственный обработчик breakpoint()

PEP 557, Data Classes

Новый модуль dataclasses делает более удобным написание классов, основная задача которых — хранить данные. Вы просто используете декоратор, и весь бойлерплейт пишется за вас.

from dataclasses import dataclass, field

@dataclass(order=True)
class Country:
    name: str
    population: int
    area: float = field(repr=False, compare=False)
    coastline: float = 0

    def beach_per_person(self):
        """Meters of coastline per person"""
        return (self.coastline * 1000) / self.population

Методы __init__, __repr__, __eq__, __ne__, __lt__, __le__, __gt__, __ge__ будут сгенерированы автоматически для класса Country

PEP 562, Кастомизация атрибутов модулей

Вы уже давно знакомы с __getattr__ для классов. Теперь этот метод может быть определён и для модулей. Типичные примеры использования: сообщить о том, что некоторая функция в модуле объявлена deprecated, а также ленивая загрузка тяжелых подмодулей.

PEP 564, Временны́е функции с наносекундным разрешением

Улучшен модуль time, добавлено несколько новых функций

time.clock_gettime_ns()
time.clock_settime_ns()
time.monotonic_ns()
time.perf_counter_ns()
time.process_time_ns()
time.time_ns()
Точность расчёта временных интервалов повышена до наносекунд

Упорядоченные словари

Порядок ключей в словарях теперь гарантированно совпадает с порядком их вставки, это добавлено в спецификацию.

>>> {"one": 1, "two": 2, "three": 3}  # Python <= 3.5
{'three': 3, 'one': 1, 'two': 2}

>>> {"one": 1, "two": 2, "three": 3}  # Python >= 3.6
{'one': 1, 'two': 2, 'three': 3}

Это работало ещё с версии 3.6, однако опиралось на внутреннюю реализацию словарей CPython, и полагаться на такой порядок было нельзя.

Новые ключевые слова: async и await

Корутины с async и await были введены в Python 3.5, однако для обратной совмесимости всё ещё можно было объявить переменные с такими именами. Теперь это будет выдавать ошибку.

>>> async = 1
  File "<stdin>", line 1
    async = 1
          ^
SyntaxError: invalid syntax

>>> def await():
  File "<stdin>", line 1
    def await():
            ^
SyntaxError: invalid syntax

Улучшение модуля asyncio

Модуль asyncio для поддержки асинхронности был представлен в Python 3.4 (введение). В Python 3.7 asyncio получил большое количество новых функций, поддержку контекстных переменных и улучшения производительности. Например, используя asyncio.run(), вы можете легко вызывать корутины из синхронного кода, не создавая event loop.

import asyncio

async def hello_world():
    print("Hello World!")

asyncio.run(hello_world())

PEP 567, Контекстные переменные

Контекстные переменные — это переменные, которые могут иметь различные значения в зависимости от окружения. Они похожи на Thread-Local Storage, в которых каждый исполняемый тред может иметь разное значение переменной, однако контекстные переменные могут иметь разные значение даже в пределах одного треда. Основная область применения — параллельные асинхронные задачи.

import contextvars

name = contextvars.ContextVar("name")
contexts = list()

def greet():
    print(f"Hello {name.get()}")

# Construct contexts and set the context variable name
for first_name in ["Steve", "Dina", "Harry"]:
    ctx = contextvars.copy_context()
    ctx.run(name.set, first_name)
    contexts.append(ctx)

# Run greet function inside each context
for ctx in reversed(contexts):
    ctx.run(greet)

Запуск скрипта приветствует Steve, Dina, и Harry в обратном порядке:

$ python3.7 context_demo.py
Hello Harry
Hello Dina
Hello Steve

Импорт файлов с данными с помощью importlib.resources

Как происходила упаковка ресурсов в пакет до Python 3.7? Обычно выбирали один из трёх способов

  • Захардкоженные пути к ресурсам
  • Поместить файлы внурь пакета и получать к ним доступ с помощью __file__
  • Использовать setuptools.pkg_resources

Первый способ не портируем. Второй подходит лучше, но если Python-пакет находится внутрь zip архива, то там не будет атрибута __file__, что создает проблемы. Третий способ работает, однако слишком медленный.

Теперь появляется ещё один способ: новый модуль importlib.resources в стандартной библиотеке. Он использует уже существующую функциональность импорта модулей для загрузки файлов. Допустим, у вас есть ресурсы внутри пакета:

data/
│
├── alice_in_wonderland.txt
└── __init__.py

Теперь вы можете получить доступ к alice_in_wonderland.txt следующим образом:

>>> from importlib import resources
>>> with resources.open_text("data", "alice_in_wonderland.txt") as fid:
...     alice = fid.readlines()
... 
>>> print("".join(alice[:7]))
CHAPTER I. Down the Rabbit-Hole

Alice was beginning to get very tired of sitting by her sister on the
bank, and of having nothing to do: once or twice she had peeped into the
book her sister was reading, but it had no pictures or conversations in
it, ‘and what is the use of a book,’ thought Alice ‘without pictures or
conversations?’

Похожая функция resources.open_binary() открывает файлы в бинарном режиме.

Оптимизации

Ни один релиз Python не обходится без набора оптимизаций. Python 3.7 не стал исключением:

  • Снижены накладные расходы при вызове многих методов из стандартной библиотеки
  • В целом методы теперь вызываются на 20% быстрее
  • Время запуска самого Python снижено на 10-30%
  • Импортирование typing теперь быстрее в 7 раз.

Различные лучшения CPython

  • Уход от ASCII как от дефолтной кодировки:
  • PEP 552, Воспроизводимые .pycs
  • Новая опция -X
    $ python3.7 -X importtime my_script.py
    import time: self [us] | cumulative | imported package
    import time:      2607 |       2607 | _frozen_importlib_external
    ...
    import time:       844 |      28866 |   importlib.resources
    import time:       404 |      30434 | plugins
    
    Вы также можете использовать -X dev для активации «режима разработки» и -X utf8 для активации режима UTF-8. Полный список опций.
  • PEP 565, улучшенная обработка DeprecationWarning

Новость на Real Python

>>> Официальный обзор изменений

★★★★★

Проверено: tailgunner ()
Последнее исправление: tailgunner (всего исправлений: 5)

Ответ на: комментарий от bread

Learning Python — графомания, негодный пример.

да, у питона даже сторонние книги - туфта, графоманские крипичи

вот если с сишарпом даже сравнивать, даже то что не сам MS извадал, а то же гнилое орайли (c# албахари тот же) совсем другой уровень. это при том, что MS есть нормальная бесплатная документация, качественная

anonymous
()
Ответ на: комментарий от tailgunner

Документация у Python нормальная (да, я работал с Java и сравниваю с ней).

да вы поехавшие тут все

anonymous
()
Ответ на: комментарий от tailgunner

Модули [...]

Не являются частью языка.

уууу казуистика пошла типичная твоя изворотливая. ну это бред, то что ты говоришь. стандартная библиотека питона - это и есть часть питона. и всё тут. точка.

anonymous
()
Ответ на: комментарий от anonymous

Обычно годные книги пишут авторы, либо чуваки из core team. Но у питона и тут не заладилось почему то. Какие-то чучоные растекаются мыслью, или инженегры гугля копипастят доки.

bread
()
Ответ на: комментарий от ugoday

Господа, вы бы сначала определились с терминами: простой как лёгкий порог вхождения или простой как «просто делать сложные штуки». Это, прямо скажем, не одно и то же.

Так в том и суть, что, по утверждению анонимуса, питон не сильно отличается ни от своих «прямых конкурентов» типа руби, перла, пхп, ни даже от жавы и сишарпа по критерию «простота» (от себя добавлю — в обоих смыслах).

nisemax
()
Ответ на: комментарий от no-such-file

И какой же язык проще питона?

Среди скриптовых, любой язык проще питона. Столько ad hoc фич и синтаксиса нет просто нигде.

Python - это великолепный второй язык к которому легко возвращаться, так как в базе это просто basic с более гибким синтаксисом. Забыл что такое лямбды - пользуйся прпостыми функциями, лень вспоминать list/dict comprehensions - используй циклами. Манипуляция строками, списками, работа с csv, json - все есть «из коробки». Не нравится - изобретай свое колесо. Почитаешь доки - переделаешь в другом проекте.

anonymous
()
Ответ на: комментарий от bread

Обычно годные книги пишут авторы, либо чуваки из core team. Но у питона и тут не заладилось почему то. Какие-то чучоные растекаются мыслью, или инженегры гугля копипастят доки.

Сейчас с книгами по Python-у всё очень плохо. Его продвигают как простой язык для начинающих и полки магазинов забили творения про 2+2. Причем, пишут люди далекие от программирования.

anonymous
()
Ответ на: комментарий от tailgunner

B всё же, тейлганнер, вот вопрос, раз ты говоришь, что, мол,питоновские стандартные модули не относятся к питону, то что тогда остается? Я так понимаю ты исключил и datetime, collections, enum, threading и т.п.

Что ты под питоном тогда понимаешь? Т.е. я о питоне, а ты о чем-то совсем своем там начал думать и говорить? Может расскажешь о чем? Документация ведь наверное тоже не относится к питону, так ведь по-твоему? Ну сипитон имплементация ведь наверное? Или нет? Ты ведь какие-то свои избирательно понимание имеешь, особоенное. С чем ты пришел в разговор? Вот интересно.

«Простой язык» по моему мнению, наверное, обеспечивает хорошую кроссплатформенность и абстракцию.

По твоему мнению.

Ахаха, да, по моему мнению это так. Это я написал, не надо мне повторять что я написал. Тейлганнер ты шутник прям.

anonymous
()
Ответ на: комментарий от anonymous

Ты не передергивай. fcntl и fork это наследие UNIX и оно не должно работать везде одинаково, даже когда вызывается из Python. Наверняка, в твоем любимом языке они тоже не кроссплатформенны.

anonymous
()
Ответ на: комментарий от ugoday

В пхп, говорят, адовая неконсистентность,

Есть такое. А в питоне лямбды однострочные и Dive into python, а в пхп исчерпывающий прекрасно систематизированный справочник по языку, встроенным функциям и прочим «стандартным» и не очень библиотекам, с комментами пользователей под каждой статьей...

В каждой избушке свои погремушки.

nisemax
()
Ответ на: комментарий от anonymous

Ээээ-эээээ! Читаем внимательно, я такого не требовал и не ожидал даже. Во-первых совсем о другом говорил. Там просто контекст «простого языка» было. И вообще я считаю что это не дело (для просто языка) - пробросили а дальше делайте у себя там man 3 lockf. Во всех «простых» (не мое утверждение, я с ним спорю как раз) языках предлают man 3 lockf у себя там сами? Во многих наверное (но может быть и не во всех). Но чем он ровнее других-то тогда?

anonymous
()
Ответ на: комментарий от nisemax

а в пхп

и да, там даже ТИП возвращамого значения пишут слева от функции

int time ( void )
. И да, всегда указывают типы данных для параметров!!
string date ( string $format [, int $timestamp = time() ] )
А потом еще в стандартизированном месте (всегда в одном и том же! как им это удалется, ну вообще!) перечисляют параметры,столбиком перечисляют вы представьте: параметр-описание, параметр-описание (!!) Технологии 22 века, ждем PY5000. Хотя зачем, нет, в питоне есть же какая-то документация даром, что на программистскую не похожа, все равно: у питона ооочень хорошая документация! И вообще питон простой язык, об этом написано на каждом заборе, на каждом! Даже тут в этом треде. А еще знаете что? Но только секрету, скажу, вы только молчок, ага? [шепотом] у питона оооочень хоооороооооошая документаааааааация...

anonymous
()
Ответ на: комментарий от anonymous

Во многих наверное (но может быть и не во всех). Но чем он ровнее других-то тогда?

Ровнее стандартной библиотекой, за исключением OS специфичных системных библиотек и модулем datetime =)

anonymous
()
Ответ на: комментарий от anonymous

И да, всегда указывают типы данных для параметров!!

Что значит всегда, когда не всегда? И, да, так начудили с синтаксисом, что парсер языка без префикса названия переменной от названия функции отличить не может.

anonymous
()
Ответ на: комментарий от anonymous

Что значит всегда, когда не всегда?

Что-то не припомню такого. Может не обращал внимания и давно уже не пользуюсь пхп. Сейчас решил посмотреть, кликаю. Не приведете пример функции с параметром тип которого не указан? (mixed не считается)

anonymous
()
Ответ на: комментарий от anonymous

ну ты мне еще typeshed приведи тогда или что-нить из кишков pycharm. это не то всё же. да и я даже почти уверен что она где-то есть отрендеранная. но это не то. ты знаешь вообще есть такая штку как `pydoc -p` но там тоже информации то нет толком.

anonymous
()
Ответ на: комментарий от anonymous

Что значит всегда, когда не всегда

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

В коде тип возвращаемого значения функции задать нельзя, а тип любой переменной, в т.ч. аргумента, указать можно (только, как правило, нежелательно).

парсер языка без префикса названия переменной от названия функции отличить не может.

То ли дело в эрланге! Да?

А еще в пхп есть переменные переменные...

nisemax
()
Ответ на: комментарий от anonymous

парсер языка без префикса названия переменной от названия функции отличить не может

Это кстати удобно и повышает читабельность. Парсер не может, зато человеки могут легко и без напряга.

anonymous
()
Ответ на: комментарий от nisemax

Всегда. В документации всегда указан тип возвращаемого значения и аргументов.

Мне иногда думается (это только мои догадки, не более), что некотоые тут никогда ничего не видели, это или кругозор или что. Такой вещи как профессионально сделанный API Reference у статических языков не видели тоже, а про динамические думают, что питон - это вершина документации вообще (хотя она смехотворна, неполна и туманна). А уж на пхп.нет заглянуть гордость совсем не позволяет. Всё, я устал.

anonymous
()
Ответ на: комментарий от RazrFalcon

Я, прежде чем написать, погуглил и не нашел ffi в стандартной библиотеке рубей и джавы. Только вызов специально подготовленных so-шек, с подключенными ruby.h/jni.h. Может плохо искал

makoven ★★★★★
()
Ответ на: комментарий от anonymous

как я буду такое на php?

Обыкновенно, всё для этого есть.

для любой современной либы нужно инициализировать уродский psr-совместивый автолоадер

Для любой современной либы в питоне нужно инициализировать целый virtual env.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

Манипуляция строками, списками, работа с csv, json - все есть «из коробки»

Это практически везде есть из коробки. В том же пыхе например.

как в базе это просто basic с более гибким синтаксисом

В качестве замены бейска питон хорош, не спорю.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

али на другом фрейме

В современном пыхе composer и наличие PSR интерфейсов позволяет об этом не думать. Просто собираешь вокруг DI контейнера компоненты которые нужны.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

у питона оооочень хоооороооооошая документаааааааация...

Для начала нулевых она была ниче так. Я помню как стали у нас внедрять руби, и там было вовсе нифига (обрывочные маны на корявом инглише от японцев). Тикль я тоже учил наощупь читая код. В общем могло быть хуже, хотя доки конечно неряшливые как и весь питон.

bread
()
Ответ на: комментарий от makoven

Я, прежде чем написать, погуглил и не нашел ffi в стандартной библиотеке рубей и джавы.

Экспертиза уровня ЛОР. Хотя тут и гуглить не надо, пиши всякую ересь, кто там будет проверять. Я всегда так делаю. Если видишь пачку гневных реплик, так даже веселее.

bread
()
Ответ на: комментарий от no-such-file

Например Learning Python - 1500 страниц. Это простой язык? Для сравнения Learning Perl всего 390 страниц.

Я думаю, мы используем неверную терминологию. Правильнее говорить Питон — лёгкий язык. Вот, например, машина Тьюринга может быть описана на одной странице. Она простая, но совсем не лёгкая. И перл тоже не лёгкий. А питон лёгкий. И простой. 1500 страниц — это конечно много, но у питона лозунг «батарейки в комплекте». Если каждую батарейку хорошо описывать, там и больше может быть. В конце-концов, если у Перла начать CPAN описывать, там оver9k страниц будет. Ну и возможно, это просто детали издательского бизнеса, им удобно продавать толстые книги за много денег.

ugoday ★★★★★
()
Последнее исправление: ugoday (всего исправлений: 1)
Ответ на: комментарий от nisemax

Так в том и суть, что, по утверждению анонимуса, питон не сильно отличается ни от своих «прямых конкурентов» типа руби, перла, пхп, ни даже от жавы и сишарпа по критерию «простота» (от себя добавлю — в обоих смыслах).

Если исключить напрашивающийся вариант, что этот господин нарочно издевается, я бы предположил, что он сначала выучил java/c++/что-то ещё большое и сложное, а потом попробовал питона. Если бы движение было в обратном направлении питон->ява, то результат был бы «твою ж мать, что ж тут всё сложно-то так».

ugoday ★★★★★
()
Ответ на: комментарий от anonymous

Что ты под питоном тогда понимаешь?

https://docs.python.org/3/reference/

Т.е. я о питоне, а ты о чем-то совсем своем там начал думать и говорить?

Т.е. я хочу услышать о сложности языка Python, а ты рассказываешь мне, что у языка Python в stdlib есть модули, которые по твоему мнению, криво спроектированы.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Все, да на все. sqlite3-ruby, я так понял, не используют. Свою прослойку наваяли. Обычное явление, когда нужной функциональности нет в стандартной библиотеке и разработчик предпочел написать своё. В node.js точно такая же беда

makoven ★★★★★
()
Последнее исправление: makoven (всего исправлений: 3)
Ответ на: комментарий от anonymous

Доступ к обычному словорю емнип безопасен

Пожалуйста, укажите источник, где вы это прочли.

anonymous
()
Ответ на: комментарий от bread

Для начала нулевых она была ниче

Это неправда. Стандарты начала нулевых ничем не отличаются. Полноценная документация появилась задолго до вашего появления в программировании.

anonymous
()
Ответ на: комментарий от anonymous

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

makoven ★★★★★
()
Последнее исправление: makoven (всего исправлений: 2)
Ответ на: комментарий от makoven

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

Приходилось в нулевых совсем немного трогать с дотнет: десктопная MSDN никаких проблем с навигацией не имела, всё там нормально было. У php была скачиваемая + была CHM в ней тоже всё работало как часы, уж поудобней нынешнего. В html джавадоке фреймы работали тоже отлично. У делфи как была устроена документация не знаю, может кто-то из местных расскажет.

anonymous
()
Ответ на: комментарий от makoven

перезагружая страницу

Опять байки какие-то. С винчестера всё открывалось мгновенно, это только с CD могло побешивать пока диск не раскрутится опять, но это решается копированием.

anonymous
()
Ответ на: комментарий от anonymous

flash player - эталонное нинужно из палаты мер и весов.

Ну это только твоё личное мнение.

Может ты считаешь, что отладка тредов в питоне чем-то отличается от других языков?

В асинхронных/многопоточных программах поиск ошибок должен быть за счёт системы типов. Почитай например про Haskell, там всё сильно по другому.

Со своего рождения статическая типизация была инструментом для поиска ошибок.

Сама по себе типизация инструментом быть не может. Этим инструментом может быть компилятор который проверяет типы, но они сами по себе инструментом не являются.

Пользуйся

Двойка тебе. Во первых:

rodegast@rodegast:~$ python3 ./anonymous.py 
  File "./anonim.py", line 17
    lines = 1_000_000
                    ^
SyntaxError: invalid syntax

Во вторых ты не понял задание. У тебя действительно 3 потока, но работают они последовательно, а должны работать параллельно.

Rodegast ★★★★★
()
Ответ на: комментарий от anonymous

Множественное наследование - оно сложно само по себе, догадываюсь.

В нём нет ничего сложного.

Объявление абстрактных классов (и абстрактных методов).

Забей на них.

Rodegast ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.