Питон как был, так и остается динамически типизированным языком, а аннотации типов лишь для удобства программиста и тайпчекеров типа mypy. Да и, тем более, эти аннотации опциональны.
А что до GIL, это, в принципе, и есть самый большой костыль в языке, живущий там с момента основания, и оч хорошо, что наконец-то его решили выпилить
Но это, действительно, странно, ведь в no-gil версии используется так называемый «раздельный» счетчик ссылок: ob_ref_local и ob_ref_shared. Второй использует атомики, первый - нет. Но в случае однопоточного приложения ob_ref_shared, по логике, вообще не должен быть задействован, т.к. поток у нас только 1. Исходя из этого, имхо, не совсем понятно, откуда оверхэд на рефкаунтинг в однопоточном приложении.
Буквально пару раз в жизни столкнулся с проблемой, когда вывести нужный тип было реально больно. В подавляющем большинстве случаев - все изи. Да, занимает какое-то время "на подумать", но, кмк, этот вопрос желания.
Да что сложного в дженериках, Господи... Я - питонист до мозга костей, который, чисто баловства ради, изучает Раст на досуге. Разобраться с дженериками в расте, хотя бы на базовом уровне, мне не составило особо труда. Почему это должно быть "сложно" для других ребят-питонистов? Риторический вопрос..
Вы выражаете, как мне показалось, достаточно популярное мнение (особенно, популярное оно в среде как раз питонистов), мол, если нужно более строгое соблюдение тех или иных правил, то не нужно в целом брать Пайтон. Извините, но я с этим не согласен, причем в корне. Пайтон - отличный язык, в целом, просто он слишком... слишком много позволяет своим пользователям, а те и рады стараться) Я же лично считаю, что и на Пайтоне можно писать более-менее тайп-сэйф код, также как и контролировать мутабельность во избежание сайд-эффектов, не смотря на то, что сам язык позволяет мутэйтить почти все на свете.
Ну и как ещё один аргумент "почему Пайтон" - потому что в этом языке и у меня, и у прочих ребят в команде опыта больше, чем у любом другом. Звучит банально, но это факт.
Знаете, сколько раз я на код-ревью получал ответ (от инициатора код-ревью) в духе "ну дык этож петон! Какие дженерики??"
Мало того, что питонисты (не все, но с большего) не умеют писать нормальные тайп-анотации, так они еще и умудряются оправдывать свое неумение тем, что мол Пайтон был разработан как dynamic-typing язык, а все эти ваши type-hints - попытка сделать из Пайтона ту же Джаву и вообще, фу.
Благо дело, на текущем проекте я как раз ответственное лицо за настройку/прикуручивание всяческих линтеров. Пускай неумехи страдают :))
Multiprocessing, в целом, нужен, дабы добиться параллелизма (которого нельзя добиться, используя Потоки из-за наличия GIL), используя более "дорогую" абстракцию ОС (нежели Поток) - Процесс. - Порождение нового Процесса дороже, чем порождение нового Потока (особенно в Windows / MacOS, где Процессы spawn'ятся, а не fork'аются как в Linux); - Переключение контекста между Процессами дороже, чем между Потоками; - Так как у Процессов нет общей памяти (у каждого свой heap), то, для синхронизации оных нужно использовать всякие multiprocessing.Queue / multiprocessing.SharedMemory, которые автоматически сериализуют/десериализуют передаваемые между процессами объекты - дополнительный оверхэд.
Питон как был, так и остается динамически типизированным языком, а аннотации типов лишь для удобства программиста и тайпчекеров типа mypy. Да и, тем более, эти аннотации опциональны.
А что до GIL, это, в принципе, и есть самый большой костыль в языке, живущий там с момента основания, и оч хорошо, что наконец-то его решили выпилить
Но это, действительно, странно, ведь в no-gil версии используется так называемый «раздельный» счетчик ссылок: ob_ref_local и ob_ref_shared. Второй использует атомики, первый - нет. Но в случае однопоточного приложения ob_ref_shared, по логике, вообще не должен быть задействован, т.к. поток у нас только 1. Исходя из этого, имхо, не совсем понятно, откуда оверхэд на рефкаунтинг в однопоточном приложении.
asyncio.create_task(Server().run())
- замечательный пример dangling taskБуквально пару раз в жизни столкнулся с проблемой, когда вывести нужный тип было реально больно. В подавляющем большинстве случаев - все изи. Да, занимает какое-то время "на подумать", но, кмк, этот вопрос желания.
линтим типа через mypy
Да что сложного в дженериках, Господи... Я - питонист до мозга костей, который, чисто баловства ради, изучает Раст на досуге. Разобраться с дженериками в расте, хотя бы на базовом уровне, мне не составило особо труда. Почему это должно быть "сложно" для других ребят-питонистов? Риторический вопрос..
Вы выражаете, как мне показалось, достаточно популярное мнение (особенно, популярное оно в среде как раз питонистов), мол, если нужно более строгое соблюдение тех или иных правил, то не нужно в целом брать Пайтон. Извините, но я с этим не согласен, причем в корне. Пайтон - отличный язык, в целом, просто он слишком... слишком много позволяет своим пользователям, а те и рады стараться) Я же лично считаю, что и на Пайтоне можно писать более-менее тайп-сэйф код, также как и контролировать мутабельность во избежание сайд-эффектов, не смотря на то, что сам язык позволяет мутэйтить почти все на свете.
Ну и как ещё один аргумент "почему Пайтон" - потому что в этом языке и у меня, и у прочих ребят в команде опыта больше, чем у любом другом. Звучит банально, но это факт.
Drop semantic вроде нужна, дабы избежать double-fee / use-after-free, которые ведут к UB, нет?
Знаете, сколько раз я на код-ревью получал ответ (от инициатора код-ревью) в духе "ну дык этож петон! Какие дженерики??"
Мало того, что питонисты (не все, но с большего) не умеют писать нормальные тайп-анотации, так они еще и умудряются оправдывать свое неумение тем, что мол Пайтон был разработан как dynamic-typing язык, а все эти ваши type-hints - попытка сделать из Пайтона ту же Джаву и вообще, фу.
Благо дело, на текущем проекте я как раз ответственное лицо за настройку/прикуручивание всяческих линтеров. Пускай неумехи страдают :))
Дьявол кроется в том, что статик тайп-чекеры (mypy/pyright) - это сторонние тулы, которые:
Опциональны к использованию
Можно сконфигурировать так, дабы они были "лояльны" к проверяемому коду
Их можно "обмануть" - задизэйблить ту или иную failed проверку на уровне строчки кода/всего модуля
Писать везде Any
Отключить disallow_generics и писать аннотации для контейнерных типов в духе list/dict
Много всяких false-positive проверок (особенно в mypy)
И так далее, и тому подобное
Golang по быстродействию как С++, спасибо, заставили улыбнуться )
Язык, на котором нужно генерить тонну бойлерплейта, и топорный настолько, будто его разработали в 70-х, ммм, дайте два)
Как раз в 3.13 обещали no-gil
Multiprocessing, в целом, нужен, дабы добиться параллелизма (которого нельзя добиться, используя Потоки из-за наличия GIL), используя более "дорогую" абстракцию ОС (нежели Поток) - Процесс.
- Порождение нового Процесса дороже, чем порождение нового Потока (особенно в Windows / MacOS, где Процессы spawn'ятся, а не fork'аются как в Linux);
- Переключение контекста между Процессами дороже, чем между Потоками;
- Так как у Процессов нет общей памяти (у каждого свой heap), то, для синхронизации оных нужно использовать всякие multiprocessing.Queue / multiprocessing.SharedMemory, которые автоматически сериализуют/десериализуют передаваемые между процессами объекты - дополнительный оверхэд.