Comments 46
Почему TopologicalSorter лежит в functools? Что тут функционального?

Что происходит в выпиливанием GIL? Это самое важное, что ожидалось в 3.8, но было перенесено на следующий релиз.
Хорошие вопросы.
В bugs.python.org/issue17005 единственное побуждение положить в functool аргументировано, что топологическая сортировка «is somewhat related to total ordering», но большого обсуждения куда бы лучше положить этот класс судя по всему не было.
Про GIL, если речь про www.python.org/dev/peps/pep-0554, то похоже он перенесен на 3.10 или позднее
Что происходит в выпиливанием GIL?

Да, для меня до сих пор самое большой разочарование в Питоне — картонная многопоточность.
Для I/O всякого подходит, для вычислений — извините, плодите процессы и пиклите данные тудя сюда.


Позор для современного языка… при этом не использовать его вариантов часто нет — тонны библиотек, особенно в сфере работы с данными — только на нём.

Не отследил, спасибо.


Но мне часто приходится писать для систем вроде RH/CentOS7 где Python 3.6 — предел мечтаний. Можно, конечно, собрать последний и забандлить его в venv, но иногда это не подходит по организационным причинам.


В любом случае — надо изучить насколько оно удобно.

даже в centos8 был 3.6. Поэтому мы просто собрали 3.7 пакетами и положили в локальную репу…
GIL — зло. Но с ним, языком может пользоваться любой человек с общими знаниями о программировании (или даже без них). Вокруг меня туча народу струячит код на питоне, и я не уверен, что многие из них готовы к гонкам состояний, а многопоточность они хотят прямо сейчас.

Имхо пусть python остаётся гибким и выразительным языком. А многопоточный счёт лучше делать на golang, там для этого всё есть. Ну а если очень хочется многопоточности — есть асинхронность, что поможет в большинстве задач, типа web-бекенд, либо использовать многопроцессность, где для отстрела себе конечностей нужно приложить специальные усилия…

Гонки-то и с GIL тоже возможны. GIL позволяет разве что не сломать внутреннее состояние интерпретатора, а записать переменную невовремя из другого потока всё равно никто не мешает (как раз три дня назад дебажил одну гонку)

Да вроде не особо. Для синхронизации все равно нужны мютексы и прочее. Разве что один объект несколько тредов не смогут поломать внутри записав в него что-то одновременно.

Последнюю почти декаду многопроцессорность и многопоточность развивались не особо активно. То есть вроде они и есть, но 99% программ и программистов — просто это не используют. Наилучший показатель, что еще год назад 4х ядерные (часто 4х поточные) интелы покрывали все задачи пользователей. Большинство использовали однопоточность с костылями, чтобы работать немного быстрее на нескольких ядрах.

АМД разворошила этот улий. Когда ядер 16 и больше, уже никакие костыли не работает. То что майкрософт в прошлом году активно оптимизировала ядро под новое количество потоков — хороший показатель. Даже такие гиганты зашевелились.

В течении следующей декады умение дебажить асинхронность и гонку состояний станет необходимым для програмистов. Потому что код без этого будет работать не на порядок, а два медленнее. А за декаду — может быть и на три порядка.

Нужно ли делать условный питон 4 для многопоточности? Мое мнение — нужно. Сможет ли общество питона пережить новый мажорный релиз, когда флеймы 2/3 не утихли? Не сможет.

Если питон затянет выпиливания GIL еще на пару лет — возможно мы увидим как питон первалит пик популярности и начнется спад.
Популярность этого языка в выразительности, универсальности и замечательной способности поддаваться различным изменениям. Мало языков могут быть так неузнаваемо изменены инструментарием не выходящим за пределы стандартной библиотеки. Python — идеальный язык связки различных модулей. Это язык диспетчер. Его задача, в моём идеальном мире, выставить режимы и вызвать скомпилированный на C, C++ или что-нибудь типа golang код, после чего преобразовать результаты в необходимый вид и провести постобработку. Язык который можно расположить посредине между достаточно непростым кодом на вышеупомянутых языках и shell-скриптами (условно, но вот не знаю в ОС где нет shell чего-нибудь адекватного этому). Это язык на котором нужно писать, когда логика, реализованная на shell, уже взрывает мозг или выглядит страшно, но ещё нет таких требований к скорости счёта, чтобы писать на С и подобных. Это явно покрывает больше половины прикладных задач обычных людей. Данная ниша позволит держать язык выразительным и не набивать его костылями. Язык нужно оптимизировать, увеличивать скорость написанных на нём приложений, но нельзя пытаться ворваться в чужую нишу, можно застрять посередине и быть одинаково бесполезным в обеих.

Мне вообще кажется, что попытки построить универсальный язык на все случаи жизни породило море уродов и нанесло в мир ИТ слишком много энтропии… Но это моё мнение.
Я согласен с выразительностью. НО!

1) Язык уже несколько лет пичкают костылями. Я уже не знаю вещей, которые в питоне можно сделать 1 спсобом, а не несколькими. А это прямое противаречие зен. То есть в моих глазах питон — уже «урод». Хотя все еще лучше большинства.

2) Котлин и раст могут быть очень сильно изменены. Котлин так вообще рекламируется что на нем можно писать DSL прямо из языка. Я даже ловил минусы когда обсуждаел эту тему в посте ителж идеи.

Раст вообще сделан именно для этой задачи — возможность на ASM.js использовать/создать любой язык.

Из того что я вижу, условная половина языков новой волны — выполняют это требование.

3) Питон стоит у истоков всех трендов где многопоточность нужна. ИИ, биг дата, моделирование, микросервисы, скриптинг. Окей, все кроме игр. Мне сложно предствавить сколько костылей там вставленно для каждой задачи на уровне кровавого ентерпрайза. Именно эти тренды делают питон одним из самых (имхо — самым) распростаненных языков. И количество костылей там только растет. Это только вопрос времени, когда в каждой из областей свичнутся, если питон не начнет решать свои проблемы.

Потому что я не вижу как общество питона ценит эти области. У каждой области есть свои либы. И эти либы активно дрейфуют от языка. Они уже патчат ядро спитона. Дальше только форк на отдельный язык. Но потому что общество не ценит тренды — сам язык тоже от них дрейфует.

4) CPython как проект на С — очень плохого качества. И технический долг там уже сильно мешает внедрять новые полезные вещи. Кстати, это причина которая привела к тому, что гугл остался на 2 и будет ее сам патчить.

Получается смешно. Чтобы починить причину конфликта питон2/3 надо создать новый конфликт — питон3/4.
Кстати, это причина которая привела к тому, что гугл остался на 2 и будет ее сам патчить.


А где можно об этом почитать? Вроде гугл задеприкейтил python2 и всеми силами мигрирует на python3.
Это больше следствие инерции внедрения, чем принципиальных проблем нового языка или кода реализации.

Хотя есть факторы и в пользу старого языка. У меня есть большой проект сетевого общения (не HTTP), так там переход на Py3 замедлил скорость процентов на 10 из-за того, что после первичного парсинга байтового прихода с сети — идёт конверсия в строки и уже дальше работа с str (которая в нём unicode). Конечно, ускорение процессоров снивелирует эту регрессию, но всё равно как-то не очень хорошо…

Но ведь ничто не мешает продолжать работать с байтами без юникода, не? Почти всё, что можно делать с юникодными строками, можно делать и с байтами

Я не совсем понимаю 3 пункт. Биг дата, ии, моделирование и прочие задачи написаны на си, плюсах, фортране и имеют обертку в виде питона. Они уже используют многопоточность, каким образом «реальная» многопоточность в питоне сможет помочь в этих задачах? Перепишут ли математические библиотеки с си на питон? — нет. Станет ли кто-то использовать го для интерактивной работы с датафреймами вместо питона? — очень сильно сомневаюсь. Сможет ли многопоточный питон противостоять го в микросервисном мире, где нужна условно высокая производительность — нет, да и зачем? Останется ли питон в вебе — да, просто потому, что писать «не хайлоад» на джанге просто приятней чем на го.
Многие вещи начинались в университетах на чистом питоне. Потому они взрослели и их ускоряли вставками си или обертками старых решений. И сейчас действительно сложно сказать, что это были питон проекты. Но они ими были. И в этом проблема.

Эти проекты не могут оставаться в питоне, а питон не хочет замечать и идти им на встречу.

PyPy, с другой стороны, как раз пытается идти на встречу таким проектам.
Думаете, что в ближайшие годы такому «клею» можно обойтись без удобной многопоточности? Вот не думаю честно, что это так.
Сейчас го — очень активно занимает нишу «клея». Хочу заметить что MVP и бизнес логика — другая ниша. А скриптинг — третья.

И да, в клее без многопоточности никак.

В скриптинге питон все еще король.
Обо всем этом Герб Саттер писал еще в 2005 году. Более того, программисты, ученые и исследователи тоже не сидели на месте все эти годы — языки программирования, библиотеки, подходы и паттерны программирования получили огромное развитие. Все эти средства, при должном использовании, помогают сильно облегчить разработку и уменьшить количество ошибок в коде.

Сейчас есть некоторый хайп вокруг Julia. Кто знает, может это и будет новым «питоном 4 для многопоточности».
Да я читал. Но на практике мы очень долго сидели на 4 потоках. И костыли работали. Когда количество потоков перевалило за 12 в массовом рынке (или когда стали всем доступны 16) выяснилось что большинство софта было написано под «несколько поточность» а не «труъ многопоточность». Все начали обновлять софт. Из професионального софта только продукты адобе все еще не умеют в многопоточность.

Теперь когда 8 потоков будет в каждом ноутбуке — правила сильно меняются.
А многопоточный счёт лучше делать на golang, там для этого всё есть.

Да я бы рад, но вот мне допустим нужно немного ML сделать, искать аномалии в Timeseries данных. Для этого мне надо обучить моделек и гонять forecast по новым данным. А это сильно CPU-bound задача.


В Go полторы библиотеки для этого и те, скорее всего, заброшены. В Питоне — дофигищи. Поэтому пришлось брать его и костылять там всё это в подпроцессах через (де)сериализацию туда-сюда. Потому что за 30 лет питонцы не осилили мультитрединг, не говоря уже о (ко/го)рутинах...


Так что, на мой взгляд, язык определяется его экосистемой — библиотеками и (упаси боже) фреймворками.

Но с ним, языком может пользоваться любой человек с общими знаниями о программировании (или даже без них).

Как обычно, как речь о питоне, так каждый встречный — программист. Будто на других языках "hello world" невозможно осилить...

> Вокруг меня туча народу струячит код на питоне, и я не уверен, что многие из них готовы к гонкам состояний, а многопоточность они хотят прямо сейчас.

1. GIL никак не мешает сделать гонки при некорректной работе, начиная с манипуляцией общими данными за пределами мьютекса. Они реже и менее проблемны, да — segfault не поймаете — но это заслуга языка с AMM, а не GIL.

2. На сейчас планы по выпиливанию GIL состоят в том, что в пределах одного процесса можно создать подпроцесс со своим пучком тредов и взаимодействовать с ним точно так же, как сейчас модуль multiprocessing делает это для отдельных процессов. Поэтому такая реализация ничего вам не сломает — просто для 99% кода можно будет заменить слово multiprocessing на его новый аналог.
Почему TopologicalSorter лежит в functools? Что тут функционального?

На правах шутки: Потому что это свалка для вещей, которые не нужны Гвидо.


Guido:


“I value readability and usefulness for real code. There are some places where map() and filter() make sense, and for other places Python has list comprehensions. I ended up hating reduce() because it was almost exclusively used (a) to implement sum(), or (b) to write unreadable code. So we added built-in sum() at the same time we demoted reduce() from a built-in to something in functools (which is a dumping ground for stuff I don’t really care about :-).”
Не удивлюсь, если это реальная причина. И на фоне возрождения тренда функциональщины оно еще аукнется питону.
Ускорены встроенные типы (range, tuple, set, frozenset, list) (PEP-590)

Не смог после прочтения Пепа сделать аналогичный вывод. Не могли бы немного конкретизировать?
Действительно, мне стоило углубиться в этот вопрос, а то не очень понятно, что имелось ввиду в описании релиза под «builtins are now sped up».
Если я правильно понимаю, речь идет о том, что благодаря этому соглашению, ускорится производительность вызова, за счет того, что будет создаваться меньше промежуточных структур в процессе. В любом случае, это больше касается C API, а не разработки на CPython. Однако, это если кто-то лучше вник и может вкратце пояснить, будет круто
2. Использовать lstrip, rstrip:
'foobar'.lstrip(('foo',))

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


Проблема lstrip даже не в повторениях, а в том, что он работает совсем иначе и использовать его как removeprefix/removesuffix нельзя, так что изменение довольно полезное.
>>> 'fbar'.lstrip('foo')
'bar'
>>> 'oooooobar'.lstrip('foo')
'bar'
>>> 'oofbar'.lstrip('foo')
'bar'
Спасибо за уточнение — возможно сэкономит когда нибудь пару часов дебага. Всегда думал что lstrip ищет/обрезает имеено строку, а не символы ведь я ей передаю строку, а не список символов. По мне так не очень явное поведение. Понятно что теперь из за совместимости не сделать, но если уж расматривать аргумент lstrip как итератор символов для удаления, было бы логичнее вместо добавления removeprefix изменить сигнатуру вызова lstrip: захотел удалить префик — передал ['prefix'], захотел любой из списка символов — передал 'symbols'
Новый класс functools.TopologicalSorter для топологической сортировки направленных ациклических графов


О! Здорово, а то мне самому пришлось писать.
Если вы не представляет зачем это — представьте вам нужно загрузить куда-то зависимые друг от друга вещи.
Ну например что-то A не может существовать без B.
что-то C не может существовать без A.
Что-то D не может существовать без A и без C.

Топологическая сортировка вам поможет добыть последовательность загрузки B, A, C, D.


У вас непонятный стиль маркирования общения с интерпретатором. Если просто снять с экрана, то получится (CPython, PyPy — почти одинаково):

>>> 2+3
5
>>> 2 == 3
False


а ваши примеры почему-то соответствуют такому:

2+3
>> 5
2 == 3
>> False


Это сурово анноит, прошу исправить примеры.

Объясните кто-нибудь, почему в питоне объединение 2х словарей настолько важно что под него целый оператор добавили?

Не то, чтобы прямо очень важно, сколько лет без него нормально обходились.
Но всё-таки:
1. Периодически необходимость объединить два словаря возникает. Сейчас для этого приходится пользоваться костылями типа:
res = dict1.copy()
res.update(dict2)

2. Добавление нового оператора — не такое уж значительное изменение, чтобы для него нужна была очень веская причина.
3. Для множеств подобный оператор уже давно есть, а словари, по сути, просто множества с дополнительными значениями.
Only those users with full accounts are able to leave comments. Log in, please.