Обновить
4
0

Неизвестный агрессивный человек

Отправить сообщение
ABC создавался как язык для обучения.

Еще раз. Python никогда не создавался как язык для обучения. Тот факт, что Python испытал влияние ABC, никоим образом не означает, что сам Python предназначен для тех же целей. У вас ошибка в логике.

Python никогда не создавался как язык для обучения, ты перепутал его с BASIC.
https://www.artima.com/intv/python.html

Лучше просто сошлитесь на что-нибудь.

Динамическая типизация — это немножко оксюморон, если вспомнить, зачем вообще придумали типы.

Ага, а никто и не в курсе. RTTI является тоже чем-то из области абсурда)

Ну вообще-то лучше хотя бы наличием типизации.

Python имеет сильную динамическую типизацию.


либо на самом деле пишете не на питоне, а просто дёргаете лежащую под питонолибой сишную библиотеку.

Фактически, любой код на CPython дергает вызовы С API и системные вызовы ОС.

Что я делаю не так? У меня новые атрибуты внезапно появились.

Нарочно стреляете себе в ногу в доказательство якобы плохой архитектуры языка.

image

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


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

Зачем? Если вам нужны иммутабельные элементы в контейнере, используйте для этого иммутабельные значения. Просто ((1, 2), 1), никаких проблем. Не думайте, что иммутабельность в Python должна быть эквивалентом константности из языка С.

Да?

Да.


Так а почему x[0] += 1 не создает новое значение?

Потому что присваивание элемента запрещено для иммутабельного tuple. Выражение x[0] += 1 не может создать новый x[0], поскольку такое выражение делает следующее:


i = x[0]
i += 1
x[0] = i

Операция x[0] = i не поддерживается tuple. Он никогда не меняет свои ссылки.

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


Да, типы, методы и функции из расширений тоже являются built-in, и нет, определенно не нужно менять смысл выражений (...), [...] и {...} в Python. Все, пощадите мой мозг)

Но работает x += (1, ). Что есть нецелостность языка.

Ларчик открывается просто.


>>> x = ()
>>> id(x)
140362334412872
>>> x += (1,)
>>> id(x)
140362217698360

Для иммутабельного tuple выражение x += (1,) эквивалентно x = x + (1,). Присваивается новое значение. Так работают все иммутабельные типы в Python. Мутабельные меняются "по месту".

Pickle же ж. Схоронили один класс, а достали уже в другой. Изменяемые определения классов — это почти всегда зло. Они не зло только при написании и отладке. Конкретно в случае параллельного выполнения задач изменяемые определения классов становятся злом в квадрате.

Cпойлер

image


Что не помешало Go быть статически типизированным и статически компилированным.

Почему Python должен быть статически типизированным и статически компилируемым?


Много чего в CPython нельзя изменить во время выполнения: огромные слои стаднартной реализации неподвластны динамичности, я упомянул лишь один пример в статье — невозможность переопределять стандартные списки.

Встроенные типы являются исключением. Они не подлежат изменению по соображениям производительности, но можно унаследоваться от встроенного типа и переопределить или дополнить его поведение, а из-за утиной типизации в общем случае нет нужды ожидать именно list или dict — достаточно объекта, который реализует набор методов.


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

Такая гибкость является намеренной фишкой Python, которая отличает его от других языков.


with — не понимаю претензии, где тут goto? Вызов функции, как и вызов вложенного блока в нотации with, не нарушает структурированности кода.

Там же, где try/except/finally, только под другим соусом. Не нарушает структурированности кода сам по себе, точно так же как его не нарушают yield/await, которые выполняются строго последовательно в пределах сопрограммы. При await планировщик может передать управление другой сопрограмме, но этот процесс скрыт от программиста, и вам не нужно следить за этим. Вы же не нарекаете на то, что вытесняющая многозадачность средствами ОС нарушает структурированность исходного кода?)

Если придираться к деталям, то генераторы — это самые что ни на есть зеленые потоки, а вызов next/yield переключает контекст. Это не вызов сопрограммы, потому что точка входа неопределена — вызывающая функция не знает, что вызывает.

Генераторы и корутины являются сопрограммами. Я не представляю, откуда вы берете все эти идеи.

Попробуй сделать int.__hash__() вместо hash(int) и многое прояснится само собой.
https://docs.python.org/3/reference/datamodel.html#special-method-lookup

Ссылки на массивы формируют неявное поведение, которое непрактично. Я соглашусь разве что с тем, что нельзя менять поведение для старого кода — новые списки должны быть явно обозначены. Здесь фундаментальная проблема заключается даже не в списках, а в отсутствии явного разграничения значений и ссылок на значения.

В питоне все значения имеют ссылочный характер. Любая переменная является ссылкой на значение (указателем/ссылкой в терминах C/C++), передача по значению отсутствует. Однако существуют неизменяемые объекты (int, float, tuple, str, frozenset etc), когда при модификации с ссылкой связывается новое вычисленное значение вместо модификации "по месту". Именно поэтому x[0] += 1 с tuple не работает.


https://ru.wikipedia.org/wiki/Стратегия_вычисления#Вызов_посоиспользованию(call_by_sharing)

не дают модульно тестировать. Правильно отработавший в тесте кусок кода может выдать ошибку при работе целой системы, и никак вы от этого не защититесь в рамках CPython;

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


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

Это следствие динамизма и утиной типизации, основных фич питона. Разумеется, что класс (как и почти любая вещь в питоне) может быть изменен во время выполнения. Даже байкод.


не состыковываются с параллельным выполнением кода. Например, тот же multiprocessing работает с копиями определений классов, и если вы не дай бог измените описание классов в одной из копий, то ваше приложение рискует развалиться.

Потому что multiprocessing работает с разными процессами, у которых внезапно разные адресные пространства. Причем тут питон?


Более тонкий вариант динамических классов — это переопределение доступа к атрибутам через getattribute, getattr и прочие. Зачастую они используются в качестве обычных геттеров-сеттеров, для делегации функций объекту-полю, и изредка — для организации DSL.

И что из этого следует? Эти магические методы обычно используются в библиотеках, фреймворках, и там, где необходимо переопредлить логику поиска атрибутов. В обычном коде встречается редко.


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

(См. выше) К слову, почему "это все-таки должен быть специализированный инструмент"? Что подразумевается под этим? Он должен быть статическим?


Это прямо-таки запущенный случай GoTo, когда выполнение не просто бесконтрольно прыгает по коду — оно прыгает по стэкам.

Я не понимаю каким образом сопрограммы и корутины являются запущенным случаем goto. Исключения, continue, break, with, return тоже можно рассматривать как частный случай goto.


float a = 2.0;
float *src = &a;
char *dest = malloc(sizeof(float));
memcpy(dest, src, sizeof(float));
printf("%f", *(double*)dest);

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


В статье много рациональных зёрен, но они размазаны по стене текста с неясными претензиями.

Адрес почты регистрозависим! По крайней мере до знака @.

Строго говоря, строка ДО знака @ НЕ является регистрозависимой или регистронезависимой. Это определено реализацией сервера. Строка ПОСЛЕ @ адресует сервер, и она является регистроНЕзависимой. Извините за мой французский.

Нет. Локальная часть до @ интерпретируется сервером. Домен к регистру не чувствителен.
https://tools.ietf.org/html/rfc5321#section-2.3.11

Зачёт-то поставили?

Так делают. Elasticsearch передает запросы в теле методом GET, и он так же позволяет производить поиск методом POST. Его поисковые запросы могут быть внушительными)


https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html
https://developer.twitter.com/en/docs/api-reference-index.html


A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
https://tools.ietf.org/html/rfc7231#section-4.3.1

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность