Почему в Python реализована глобальная функция len() и что об этом говорит Гвидо ван Россум?

Почему в Python реализована глобальная функция len() и что об этом говорит Гвидо ван Россум?
Мой курс «Хардкорная веб-разработка» - course.to.digital
Книжный клуб:
t.me/t0digital/528
botanim.to.digital/
botanim_to_digital_bot.t.me/
Telegram - t.me/t0digital
ВК - digitalize.team
RuTube - rutube.ru/channel/24802975/ab...
Дзен - dzen.ru/id/6235d32cb64df01e6e...

Пікірлер: 149

  • @forsee2328
    @forsee2328 Жыл бұрын

    Вообще главная фишка python - это его предсказуемость. Недавно читал fluent python, там у Рамальо была такая мысль - "магические" методы в пайтоне как раз таки исключают всю магию, т.к. они делают поведение объектов понятным и предсказуемым. Ты всегда знаешь, или можешь посмотреть, в какой момент что именно вызывается и как работает. Иметь одинаковые элементы интерфейса для вообще всего в языке, начиная от билтинов и заканчивая кастомными объектами со сложным поведением - невероятно удобно.

  • @user-hy4jc3dj7z
    @user-hy4jc3dj7z Жыл бұрын

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

  • @OlViktorovich

    @OlViktorovich

    Жыл бұрын

    из опыта скажу: как русскоязычному самое сложное это придумать названия пакетов и классов в соответствии с ожидаемым от них содержимым и при написании своего движка wsgi надергал названий из starlette и werkzeug, а так же из архитектуры самого http думаю по большинству задач уже есть толковые библиотеки и если залезть к ним под капот ... можно смело заимствовать ... )) добавить решил, в своем движке поначалу использовал название emitter и emit (дёрнутые из php движка) при callback заголовков и return list[bytes] а потом переписал на def __call__(self, env: dict, callback: callable) -> list[bytes]: return [Http(env)(callback)]

  • @user-hy4jc3dj7z

    @user-hy4jc3dj7z

    Жыл бұрын

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

  • @OlViktorovich

    @OlViktorovich

    Жыл бұрын

    @@user-hy4jc3dj7z делаю так - пишу до рабочего состояния модель (даже скорее каркас), до реального выхлопа ... потом шлифую и иногда даже в каркас залезаю (например Emit на Http заменил, но там по логике это само напрашивалось, php вообще избыточностью болеет) ... главное Это Рабочее ))

  • @forsee2328

    @forsee2328

    Жыл бұрын

    @@user-hy4jc3dj7z Это настолько обширная тема, что пары видосов не хватит Тут можно выделить 2 большие темы - архитектура и архитектурные паттерны, и дизайн паттерны Почему именно паттерны - потому что во-первых нет смысла придумывать велосипеды, во-вторых с них проще начать обучение и развить интуицию для использования более абстрактных принципов По поводу дизайна - советую просмотреть все, что есть на канале ArjanCodes, а также разобраться с grasp/solid, которые являются фундаментом всех паттернов и подходов По поводу архитектуры - тут конкретные источники информации дать сложнее, я бы на твоем месте залез в гитхаб, нашел бы там штук 5 популярных опенсорсных проектов, похожих на то, что делаешь ты, и попытался понять их структуру. С большой долей вероятности там можно будет разглядеть MVC. Еще есть канал Continuous Delivery, там говорится не только про архитектуру, но и про пайплайны и методологии разработки, все это тоже очень полезно, особенно когда уже есть опыт пары проектов Еще есть несколько неплохих лекций от Сергея Немчинского, если не смущает java

  • @user-hy4jc3dj7z

    @user-hy4jc3dj7z

    Жыл бұрын

    @@OlViktorovich я тоже примерно так же, но всеравно ощущение что я чего то не понимаю, не всегда получается хорошо )

  • @DimPyProg
    @DimPyProg Жыл бұрын

    Побольше таких видосов Можно даже отдельный плейлист для таких видосов сделать Там можно рассказывать такие вещи как раз, когда читаешь книги Или делать по каждой книге отдельный плейлист и там какие-то резюмирующие видосы по темам

  • @rockkley9159
    @rockkley9159 Жыл бұрын

    Спасибо за информацию! И классная футболка!

  • @t0digital

    @t0digital

    Жыл бұрын

    Спасибооо:)!

  • @Malefaro
    @Malefaro Жыл бұрын

    Как по мне худшее что есть в python'e это выбор префиксной нотации для len, filter, map и тд. 1. Это абсолютно не удобно для написания кода, т.к. мы думаем последовательно, а не с конца. И если мне надо отфильтровать список, затем преобразовать, и просуммировать я так и хочу писать код, а не начинать думать с конца (это все равно что пытаться в голове слово задом наперед прочитать) Пример: postfix: `result = lst.filter(lambda x: x%2==0).map(lambda x: x**2).reduce(lambda a,b: a+b)` prefix: `result = reduce(lambda a,b: a+b, map(lambda x: x**2, filter(lambda x: x%2==0, lst)))` Во втором случае если я буду писать код последовательно я буду как дурак мотать курсор то в начало то в конец(сначала напишу filter(...) потом переведу курсор в начало чтобы написать вокруг него map и тд), ну либо заставлю думать себя с конца. С len тоже самое. Постоянно возвращаю курсор в начало... len(filter(lambda x: x%2==0, lst)) vs lst.filter(lambda x:x%2==0).len() 2. Это неудобно исправлять. Если надо что-то поменять или не дай бог добавить какую-то операцию в середину ... проще переписать всё заново чем найти где нужная лямбда и где нужная скобка. 3. Это нечитабельно. Глядя на примеры выше гораздо проще понять что происходит в постфиксном варианте. Человек читает слева->направо, сверху->вниз (если вы конечно не араб) и сразу понимает что происходит ибо каждое действие перед ним. В префиксном же надо либо читать справа->налево что неестественно и неудобно, либо держать в голове ВСЕ операции до последней чтобы сложить итоговую картинку Так что не знаю про какое "упрощение взаимодействия человека и компьютера" идет речь. Для меня это главное усложнение. И для написание и для прочтения. Так что больше похоже на попытку оправдать своё(Гвидо) мимолетное увлечение функциональным программированием Хотя даже в функциональных языках понимают как это неудобно и у них есть pipe операторы чтобы писать код последовательно... P.S. вы конечно можете сказать "да кто вообще пользуется filter, map, reduce, а без них с одним префиксным len можно жить" ну так ими оттого то и не пользуются что это неудобно. С тех пор как начал писать на rust'e в 90% случаев использую итераторы и стримы вместо циклов. Так гораздо удобнее читать и понимать код ибо каждое действие логически отделено и понятно что ты делаешь на каждом конкретном этапе. Вместо 1 цикла for на кучу строк в котором все вперемешку. И даже с одним len мне лично проще постфиксная запись так как я привык думать "мне надо взять переменную и получить её длину" и сначала пишу переменную и возвращаю курсор назад. Создатели Go тоже решили сделать себе функцию len (для их 2ух контейнеров:D) вместо метода, вот и там постоянно сталкиваюсь с отголосками ...

  • @SkipIntr0

    @SkipIntr0

    6 ай бұрын

    Согласен, ни один до доводов в видео не был убедителен. После многих лет работы с Ruby, где как раз-таки есть то самое единство и универсальность (всё - объекты классов, все работает через методы, глобальные функции (методы класса Kernel) нужны для самых общих вещей и крайне редко), о котором говорится в этом видео (правда, я так и не понял, о каком единстве может идти речь, если половина из наиболее используемых встроенных функций реализованы через глобальные функции, а другая половина - через методы классов) так и не понял, за что Python в итоге получил на столько большую аудиторию и признание, чем его главный конкурент на определенном периоде развития интерпретируемых языков.

  • @mongoose144
    @mongoose14411 ай бұрын

    Очень интересная рубрика, ещё хотелось бы подобные видео про методы строк, списков итд.

  • @knarg4682
    @knarg468214 күн бұрын

    Контейнеры -- это хорошо. Но неплохо бы добавить упоминание о, например, такой штуке как range. Которое вообще не контейнер, элементов пока ещё не существует. Что аж никак не мешает применить функцию len и не париться, как именно она получила "длину" этого диапазона.

  • @evgeny1775
    @evgeny1775 Жыл бұрын

    Алексей, спасибо ❤ Смотрю каждый видос, покупаю все твои продукты (книжный клуб, курс и тд) Общаюсь с тобой в чатах Следующий шаг только вживую за чашкой чая чиллить

  • @t0digital

    @t0digital

    Жыл бұрын

    Спасибооо!

  • @vintets

    @vintets

    Жыл бұрын

    Спасибо, то, спасибо, но не пригласил 😆

  • @ozodsaidov7427
    @ozodsaidov7427 Жыл бұрын

    Привет Алексей! Как ваше мнение по EAV концепций. Расскажите нам об этом.

  • @unix3d
    @unix3d Жыл бұрын

    __init__ это не конструктор. В Python конструктором является __new__ так как именно этот метод создает экземпляр объекта, а __init__ отвечает за инициализацию экземпляра после его создания. То что в C++/C#/Java и др. называют конструктором в Python представлено последовательным вызовом методов __new__ (для создания) а вслед за ним __init__ (для инициализации) экземпляра.

  • @t0digital

    @t0digital

    Жыл бұрын

    Да

  • @Splish_Splash

    @Splish_Splash

    Жыл бұрын

    Это занудство, для упрощения инит называют конструктором просто потому что он выполняет ту же работу что и конструкторы в других языка, new переопределяется гораздо реже

  • @unix3d

    @unix3d

    Жыл бұрын

    @@Splish_Splash, это не упрощение как Вы считаете, а банальная не хватка знания или не понимание как это работает на более глубоком уровне и чем по своей сути является реальный конструктор (если про Python то что же делает __new__), что происходит в памяти в этот момент. Как проходит первичное выделение памяти, как проходит первичная инициализация значениями по умолчанию для вещественых и ссылочных типов. по этому в среде Python разработчиков и укаренилось то что __init__ стал конструктором. Можете считать меня занудой (*мне плевать) З.Ы. посмотрите на дасуге как в pathlib определяется класс пути в зависимости от OS на которой запускается, может тогда Вас это подталкнет к изучению внутренностей что находится под капотом.

  • @goartlosterd993

    @goartlosterd993

    Жыл бұрын

    @@unix3d почему вы в словах заменяете букву "о" на "а"? Это же банальная нехватка знания языка!

  • @knarg4682

    @knarg4682

    14 күн бұрын

    @@goartlosterd993 там вообще кровь из глаз))) Код мы, значит, соблюдаем до запятой, иначе тупо не взлетит, а свой же нативный язык можно говнить как угодно, "итак панятна што йа хател сказать мыни на игзамине Мамку сваю учить будиш".

  • @nadyashaymardanova6000
    @nadyashaymardanova6000 Жыл бұрын

    Здорово!

  • @YanchikDev
    @YanchikDev11 ай бұрын

    01:14 для Django QuerySet лучше не использовать len(), ибо это неэффективно в случае если нужно узнать сколько в БД объектов лежит, запрос будет вида SELECT * В таких случаях лучше использовать queryset.count(), и тогда запрос будет вида SELECT COUNT(*), который выполняется гораздо быстрее. UPD: в видео было сказано про .count()

  • @ololobro
    @ololobro Жыл бұрын

    лайк за микрофон Союз !)

  • @Vjidowkdkcpapqkfjfw
    @Vjidowkdkcpapqkfjfw Жыл бұрын

    Благодарю! Хочется тоже прочитать эту книжку, но сейчас посмотрел на её толстоту и что-то задумался) Тяжело читается ?

  • @t0digital

    @t0digital

    Жыл бұрын

    и да, и нет - неоднозначно:)

  • @VL4STEL1N
    @VL4STEL1N Жыл бұрын

    Можешь пожалуйста записать видосик по установки C++ на nvim, а то в инете слишком много разной инфы и так как я новый пользователь, совсем уже запутался. Я думаю многим бы это помогло ))

  • @khnykaq8823

    @khnykaq8823

    Жыл бұрын

    буквально вчера смотрел одного товарища, он сказал, что главное - это настойчивость. Только что потратил 4,5 часа на установку виртуальной машины. Грешил на старый ноут (10 лет с момента покупки), старый Пайтон (стоит 3.8), но в результате все таки установилось. Ща бум смотреть, работает ли?))) (Для справедливости, нужно сказать, что с полгода назад, когда начинал с Питоном, тоже попробовал nvim, показалось интуитивно непонятным - и забросил)

  • @andruhaz
    @andruhaz Жыл бұрын

    Любопытно однако...что сделало garage: итерируемым- неужели переопределение __getitem__ ? В моей картине мира for in должен начать искать реализацию iter/next в классе и использовать ее инструкции для итерирования

  • @user-iu2df5ey2v
    @user-iu2df5ey2v Жыл бұрын

    Блин, теперь я не смогу на собесах козырять этой инфой, а всё их-за вас!!! Но контент годный конечно

  • @olimjonnematov8173
    @olimjonnematov8173 Жыл бұрын

    Можно пожалуйста ссылку на статью Guido van Rossum

  • @t0digital

    @t0digital

    Жыл бұрын

    mail.python.org/pipermail/python-3000/2006-November/004643.html docs.python.org/3/faq/design.html#why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list

  • @zzzzzzzz6792
    @zzzzzzzz6792 Жыл бұрын

    Можно гайд про рандом?

  • @rusnickk
    @rusnickk Жыл бұрын

    Интересны комментарии Гвидо, а мне казалось, что len это влияние функционального подхода на Python, когда можно строить выражения типа max(map(len, words))

  • @lzrdblzzrd
    @lzrdblzzrd Жыл бұрын

    Подскажите что за микрофон? Выглядит круто.

  • @t0digital

    @t0digital

    Жыл бұрын

    Союз 013

  • @lzrdblzzrd

    @lzrdblzzrd

    Жыл бұрын

    @@t0digital спасибо!

  • @Alexey-gp7vc
    @Alexey-gp7vc Жыл бұрын

    Читаемость - дело вкуса. Логика такого решения в питоне вполне понятна. Я питон люблю, но лично мне больше по вкусу, когда в языке придерживаются fluent interface т.е. цепочек методов. Так в большинстве мейнстримных языков, особенно в JS/Ruby/Kotlin. Или когда есть пайпы (pipe-оператор), как, например, в Elixir. Да, у этих подходов есть свои минусы. Но, в целом, а) единообразие рулит б) код весьма читабелен с адекватным форматированием в) не ломаешь голову над промежуточными переменными. В питоне это не то чтобы прям проблема-проблема т.к. язык более чем позволяет писать элегантно/лаконично и при этом читабельно. Но пайпы точно не помешали бы т.к. временами охота херак-херак и тудой. А не ломать голову как назвать переменную (или функцию) с промежуточным результатом т.к. если её не вводить, то будет уродливая и нечитабельная солянка из вложенных вызовов функций и цепочек вызовов методов. В общем - хочу в питоне пайпы, константы и явное определение переменных... и чтобы всё было выражением, и акторы, и статическую сборку в бинарник 😀(хаскель/руби не предлагать))

  • @andruhaz

    @andruhaz

    Жыл бұрын

    Есть такой питон уже)))). Rust называется. Все как вы хотите (почти). Я бы тоже поддержал бы ваши предложения, как и еще много народа. Есть несколько интерпретаторов с JIT, посмотрите ради любопытства проекты Pyjion, Pyston может зайдет. Но Гвидо и Ко сцко непрошибаемы, там ничего интересного не будет вообще. Дай ему бог хоть от GIL избавиться. Я смотрел интервью с ним в оригинале ваще хотел на следующий день с питоном завязать

  • @Alexey-gp7vc

    @Alexey-gp7vc

    Жыл бұрын

    @@andruhaz да, в расте много чего есть и даже больше (компилятор шикарен и концепция владения очень интересная). Но с ним проблемы почти такие же как и с хаскелем, имхо. Во-первых, для его сознательного использования надо быть чутка умнее (сильно так "чутка"). Во-вторых - область применения, которая налагает ещё бОльшие требования к мозгам и глубине понимания (системная разработка/хайлоад/математика). В-третьих - востребованность. Хотя на хаскелле бэкенды вполне себе пишут, даже есть фирма которая джунов принимает... но это не для слабых духом. Да и на расте тоже начинают идти в веб, но снова таки - порог... Поэтому хотелось бы, чтобы питон развивался в "правильную" сторону, не требуя при этом слишком много мозга 😀 Так-то паттерн матчинг уже завезли (в руби он лучше удался из-за чутка другой философии языка, зато у js/ts и такого нет). С сабинтерпретаторами возможно завезут CSP (не акторы, но тоже хорошо...снова таки в руби ракторы пораньше завезли, но они ещё остаются экспериментальными). Типизация постоянно совершенствуется (до уровня ts, конечно, не дойдём, но может оно и хорошо). Сейчас ещё скорость подшаманят с jit, а там может и до aot доберемся со временем (хотя это очень вряд ли... та же GraalVM у джавистов далеко не сразу появилась, а тут масштабы и ресурсы далеко не те же, плюс докер решает многие проблемы). Вот пайпы и прочая функциональщина (монады, например) - это конечно вряд ли когда-то появится, философия языка совсем не та.

  • @Alexey-gp7vc

    @Alexey-gp7vc

    Жыл бұрын

    ​@@andruhaz не сразу увидел изменения ответа) Да, я видел Pyjion, Pyston, само собой ещё и PyPy, mypyc, Nimba - ситуативно они конечно применимы, но в целом да, увы не то. Интервью тоже смотрел (в том числе у Лекса Фридмана). Что поделать - опыт перехода с 2 на 3 настолько испугал всех в индустрии, что теперь обратная совместимость это ловушка на десятилетия. Да можно и на тот же Perl посмотреть - вот появился Raku, а уже никому нафиг не нужен... У того же Go есть уйма первоначальных просчётов и глупых ошибок, но уже никуда не деться. Имхо, GIL так или иначе преодолеют (возможно, что даже просто сабинтерпретаторов будет достаточно). Скорость, надеюсь, тоже поднимут хотя бы чуть ближе к ноде и пхп. А в остальном конечно язык не в той фазе развития, чтобы активно добавлять вкусности. Скорее его надо отполировать, чтобы им было приятней пользоваться. Тот же инструментарий вокруг починить (одни только пакетные менеджеры чего стоят), старьё выпилить из стдлиб (этим активно занимаются) и тд и тп. Но кто знает, может быть таки решаться на изменения в с-апи и тогда можно ожидать интересностей :) p.s. если не питон, то что?) В других мейнстримных стеках тоже свои приколы, а тут всё родное уже)) (хоть, местами, хаотичное и кривое 😀)

  • @andruhaz

    @andruhaz

    Жыл бұрын

    @@Alexey-gp7vc У вас очень интересный развернутый комментарий, прочитал как статью на ХАБРЕ). Только добавлю, что, например, мне хотелось бы поплотнее попробовать Rust, так как на нем не только будут писать производительные бэкенды, но и генерировать Webassembly, а это уже действительно становится интересным. Что касается АОТ и остального, думаю, что быстрее будет выучить другой язык, где это все есть, чем ждать Гвидо.

  • @Alexey-gp7vc

    @Alexey-gp7vc

    Жыл бұрын

    ​@@andruhaz спасибо)) Тоже охота углубиться в раст, но боюсь гнаться за всеми зайцами (их и так целое "стадо"), да и порог вхождения чутка отпугивает) И про wasm вы правы, действительно небезынтересная штука. Причём не только для веба - например, в комьюнити разработчиков текстового редактора helix (кстати, написанного на расте) wasm всерьез рассматривался как один из вариантов для реализации системы плагинов. Кто знает, может быть со временем это станет универсальным форматом. Про AOT - да, если сейчас нужен статический бинарник (для какой-нить мелкой консольной утилитки, например), то проще освоить тот же Go. И кросс-компиляция отличная. И понимается буквально за 1-2 вечера на достаточном уровне. Без особого углубления в конкурентность, конечно же, но для простых кейсов этого достаточно. С конкаренси на го двоякая ситуация, с одной стороны типа CSP и на учебных примерах всё выглядит просто. А на деле вылазит столько нюансов и подводных камней, что становится ясно, что реализация csp удалась на троечку - без знания/понимания всех приколов многопоточного программирования и внутреннего устройства тех же каналов и основных гошных структур данных далеко не уедешь. Короче, реальный го далеко не такой простой, как его рекламируют, там чем дальше в лес - тем выше деревья. Но рантайм всё равно прикольный. Был бы ещё сам язык не такой бедный и неприятный, была бы отличная штука (впрочем, это лишний повод посмотреть на раст :D).

  • @GoldoEb
    @GoldoEb Жыл бұрын

    Я не очень шарю в питоне, поясните пожалуйста, разве вот это не является "переопределением" глобального метода для самописного контейнера (класса)? class Smth: def __len__(self): return len(smth) И что мне мешает возвращать какую-нибудь лажу в этом месте? Напр.: return 13 Скажем, константу, а не действительное количество элементов контейнера?

  • @forsee2328

    @forsee2328

    Жыл бұрын

    Ты можешь так сделать, но в этом просто нет смысла Дандер методы как раз таки определяют, что твой кастомный класс - это контейнер, который может содержать какое то количество элементов. Без определения этих методов твой класс просто не имеет интерфейса, позволяющего использовать его как контейнер. То, как именно ты этот метод решишь имплементировать -твое дело, если он начнет делать не то, что ты от него ожидаешь - это твоя ошибка Контейнер - это просто абстракция, у которой реализован определенный интерфейс. Если ты хочешь использовать кастомный класс как контейнер - тебе необходимо имплементировать соответствующие методы, за тебя это никто не сделает. Если тебе нужно сымитировать поведение другого iterable/sequence с добавлением своего функционала, то имеет смысл отнаследоваться от другого класса-контейнера, например листа. В таком случае весь необходимый функционал будет реализован в родительском классе и тебе ничего менять не придется

  • @t0digital

    @t0digital

    Жыл бұрын

    Ну, ты действительно можешь написать нерабочую программу - никто не может тебе запретить это сделать, никакой инструмент. Но ты не сможешь написать дандер метод который возвращает не число, и, если ты знаешь о дандер методе, то ты должен знать и для чего он нужен. А для того, чтобы реализовать обычный метод len() у объекта этого знать не нужно.

  • @GoldoEb

    @GoldoEb

    Жыл бұрын

    @@t0digital Спасибо за ответы!

  • @TheCuwe
    @TheCuwe Жыл бұрын

    Когда собрание подписчиков ?

  • @pashamix
    @pashamix Жыл бұрын

    В 1С от контейнеров есть метод Количество(). Например Список.Количество(). Массив.Количество(). ТаблицаЗначений.Количество(). Если у кого-то пошла кровь из глаз, простите...

  • @shurko

    @shurko

    Жыл бұрын

    "Количество" долго писать. Лучше "скока".

  • @t0digital

    @t0digital

    Жыл бұрын

    @@shurko и ответ - «многа»!

  • @_radja
    @_radja Жыл бұрын

    Кажется мы уже касалить этой темы вскользь, когда был сказ о том почему все таки Python так крут, там примером выступала len(). Любишь ты ее)

  • @t0digital

    @t0digital

    Жыл бұрын

    Тут просто аргументы Гвидо нашлись:)

  • @user-dr6be2yw1g
    @user-dr6be2yw1g7 ай бұрын

    Спасибо тебе за видео! Теперь не буду использовать методы классов!!! Только глобальные методы!

  • @anton_medvedev_it_life
    @anton_medvedev_it_life Жыл бұрын

    Все больше мотивируешь начать снимать уже прогерские видосики:)))

  • @nanouasyn
    @nanouasyn Жыл бұрын

    проблема в том, что фишка с магическими методами работает только для предопределённого ограниченного множества функций. скажем, мы можем предоставить реализацию для функций len, str, repr, abs, и так далее. но как только мы захотим предоставить такую же альтернативную реализацию, скажем, для max, мы обнаружим, что это сделать не получится. хотя, возможно, наш класс - это двоичная куча, которая позволяет выполнить эту операцию за O(1). хорошо было бы "перегрузить" функцию max для нашего особого контейнера, но мы не можем, потому что нет никакого __max__. вот в julia, например, это вполне возможно благодаря множественной диспетчеризации.

  • @t0digital

    @t0digital

    Жыл бұрын

    Дандер-методы - не магические методы

  • @nanouasyn

    @nanouasyn

    Жыл бұрын

    так-то и в питоне это тоже в какой-то степени возможно. но соответствующая возможность никак не будет связана с основной инфраструктурой питона, что, по сути, означает, что возможности де-факто нет

  • @nanouasyn

    @nanouasyn

    Жыл бұрын

    ​@@t0digital да ёшкин же ж кошкин. дандер-методы, протокольные методы и магические методы - синонимы. сайт питона с доками использует этот термин. но у меня никак не получается прислать ссылку с примером. сообщение автоматически удаляется, что бы я не делал.

  • @t0digital

    @t0digital

    Жыл бұрын

    @@nanouasyn да я в курсе, что в питоне дандер-методы тоже называют магическими. Вот что об этом пишет Лучано Рамальо во Fluent Python: «В словаре «The Original Hacker’s Dictionary» (www.dourish.com/goodies/ jargon.html) термин магический определяется как «еще не объясненный или слишком сложный для объяснения» или как «не раскрываемый публично механизм, позволяющий делать то, что иначе было бы невозможно». В сообществе Ruby эквиваленты специальных методов называют магическими. Многие пользователи из сообщества Python также восприняли этот термин. Лично я считаю, что специальные методы - прямая противоположность магии. В этом отношении языки Python и Ruby одинаковы: тот и другой предоставляют развитый протокол метаобъектов, отнюдь не магический, но позволяющий пользователям применять те же средства, что доступны разработчикам ядра, которые пишут интерпретаторы этих языков. Сравним это с Go. В этом языке у некоторых объектов есть действительно магические возможности, т. е. такие, которые невозможно имитировать в пользовательских типах. Например, массивы, строки и отображения в Go поддерживают использование квадратных скобок для доступа к элементам: a[i]. Но не существует способа приспособить нотацию [] к новым, определенным пользователем типам. Хуже того, в Go нет ни понятия интерфейса итерируемости, ни объекта итератора на пользовательском уровне, поэтому синтаксическая конструкция for/range ограничена поддержкой пяти «магических» встроенных типов, в т. ч. массивов, строк и отображений.»

  • @nanouasyn

    @nanouasyn

    Жыл бұрын

    @@t0digital да я тоже в курсе, читал эту книгу) и в чём-то можно согласиться с автором, однако, существует немало не самых удачных названий, которые, тем не менее, стали классическими, и уже нет смысла разводить холивары о терминах) да и в силу описанного выше, всё-таки, можно поспорить о том, уместен ли тут термин "магический", повернув логику автора против него самого. в смысле, существует возможность переопределить для пользовательского типа функцию len, но не существует способа переопределить произвольную функцию. только одну из нескольких заранее определённых встроенных функций. переопределение функции в таком разрезе - аналог нотации [] из примера. это ли не магия, когда некоторые особые функции позволяют сделать с собой нечто, что невозможно сделать с любыми другими?

  • @uicodeuz
    @uicodeuz Жыл бұрын

    Кайф

  • @devil208356
    @devil208356 Жыл бұрын

    Как по мне, при использовании префиксной нотации для использования методов (когда сперва len, а потом объект), тут есть 2 стороны медали. При написании кода стандартным способом, сразу с первого взгляда становится понятно, метод какого объекта ты используешь. И сразу понятно, по отношению к какому объекту используется. А вот с использованием префиксного способа, в больших программах читабельность только ухудшается. Ну это мое мнение, мое наблюдение, моя такая привычка.

  • @t0digital

    @t0digital

    Жыл бұрын

    вот что об этом писал Гвидо mail.python.org/pipermail/python-3000/2006-November/004643.html

  • @youtubeyoutube6205
    @youtubeyoutube62052 ай бұрын

    05:00 мне, чисто по интуиции, выглядит намного логичнее дергать .len()

  • @user-pg8ry1tm3t
    @user-pg8ry1tm3t10 ай бұрын

    Вероятно, где-то это сродни вездесущей swap в плюсах - через всю стандартную библиотеку ее сущность пронизывает все элементы - контейнеры, алгоритмы…

  • @igornovikov5385
    @igornovikov5385 Жыл бұрын

    а когда уже видео по ООП?

  • @t0digital

    @t0digital

    Жыл бұрын

    Однажды:)!

  • @the2soul

    @the2soul

    Жыл бұрын

    Однажды Ориентированное Программирование

  • @junPY
    @junPY Жыл бұрын

    👍

  • @greeshanka8283
    @greeshanka8283 Жыл бұрын

    самая желанная и офигенистическая книжулька для меня. 3300 стоит. Очень её хочу, но получится наскрести на неё только через месяца полтора. Читать pdf формат вообще не получается книги увы и ах

  • @jamjam3337
    @jamjam3337 Жыл бұрын

    👏👍

  • @stephan_inside
    @stephan_inside Жыл бұрын

    Согласен. Ни разу в голову не приходило использовать .len() или .sort().

  • @shurko

    @shurko

    Жыл бұрын

    Не согласен. Всегда по возможности стараюсь использовать __len__() , где это избавляет от лишних скобок.

  • @eugenakv
    @eugenakv Жыл бұрын

    По поводу "len(x) лучше x.len()" в Python. На самом деле в Python это лишь дело вкуса, потому что вызов len(x) это вызов x.__len__(). То есть всё равно вызывается метод, а альтернативы вообще говоря нету, разве что переписывать len. Это просто выбор: префиксная нотация либо постфиксная. Имхо, префиксная нотация ущербная, писать так нихуя не удобно. На самом деле спор про "len(x) vs x.len()" не имеет смысла в языке без перегрузки. Потому что, к примеру в С++, выбор в пользу функций имеет смысл, потому что даёт возможность расширять API других типов. Метод дописать к чужому типу нельзя, а функцию можно. Более того в плюсах можно закладываться на это в generic коде. А сочетания этого качества и удобства использования постфиксной нотации достигается в языках с методами расширения (но без использования в generic кода) либо, к примеру, в Rust. Rust в этом смысле достиг наибольшего успеха. А обмусоливание этого в который раз в Python, на мой взгляд, лишено смысла. В этом вопросе просто нету той глубины, про которую говорят.

  • @shurko

    @shurko

    Жыл бұрын

    В частных случаях префиксная полезна, правда не в Python, а в языках семейства CoffeeScript. Например нам придётся завернуть в скобки выражение, у результата которого мы хотим ывзвать метод: ('as' + 'df').len() , тогда как префиксная форма позволяет уменьшить громоздкость: len 'as" + 'df'

  • @teum3048

    @teum3048

    6 ай бұрын

    ​@@shurkoскобки мне кажется всё равно в этом случае лучше использовать. С первого взгляда не совсем понятно что с чем складываем. В данном примере это ещё более менее можно вывести, тк используется две строки и скорее-всего нельзя сложить число со строкой (если ты не JavaScript😊, хотя как это сделано в CoffeeScript я не знаю). Но если использовать две переменных, то результат становится сложно вывести явным образом

  • @harry-smith404
    @harry-smith404 Жыл бұрын

    7:37 конечно не можем, типизации то нет 🙂 Допустим, я реализую контейнер, который в методе ___Len___ вернет стрингу. Как оно тогда отработает?

  • @t0digital

    @t0digital

    Жыл бұрын

    Интерпретатор не даст, упадет ошибка

  • @harry-smith404

    @harry-smith404

    Жыл бұрын

    ​@@t0digitalугу, чекнул, есть проверка на тип. Ну, вот проверка на тип, как по мне, единственный норм аргумент для функции len(), а так это все дело привычки, какой нотацией пользоваться. Я вот привык вызывать Length или Сount() на объекте, и постоянно забывал об этом отличии в питоне. По большому счету это действительно похоже на перевызов ___len___ с проверкой типа результата и ссылки объекта на null (исходники я не смотрел).

  • @youtubeyoutube6205
    @youtubeyoutube62052 ай бұрын

    зачем в любом классе делать метод __len__, который можно переопределить (на сколько я понимаю, любой класс наследуется от базового, в котором есть метод __len__), когда можно было сделать класс что-то типа Iterable, от которого будет наследоваться list, tuple, dict и все твои самописные итерируемые классы? на подобие как организовано в c# с колекциями

  • @ecbacs
    @ecbacs Жыл бұрын

    собственно пример с 5 яблоками как бы сам себя и убивает. информативности по факту было одинаково в обоих случаях. так же как Вам никто не мешал в постфиксной нотации вернуть ерунду, так же Вам никто не мешает ерунду написать в методе ___len___ и получить то же самое. не наброс на нотацию, наброс скорее на пример, ГВР не какой-то там небожитель, ребята писали прекрасные языки с постфиксными нотациями и найдут там миллион плюсов. я б сказал так - ГВР захотел, сделал. молодец. для себя оправдывать такое решение и высасывать из пальца его гениальность - да просто пользуйтесь как дали

  • @shavedfish3213
    @shavedfish3213 Жыл бұрын

    Здарова катаны, такой вопрос возник, который я даже и ненагуглил. Кто такие "катанЫ"?

  • @t0digital

    @t0digital

    Жыл бұрын

    Котаны. От кот и друганы

  • @user-ky5mi4gh9o
    @user-ky5mi4gh9o Жыл бұрын

    Питон был бы норм как язык программирования. Если бы не динамическая типизация

  • @t0digital

    @t0digital

    Жыл бұрын

    это был бы уже не питон. Выбрасывайте сразу тонну встроенных и сторонних библиотек

  • @NearBirdsamp
    @NearBirdsamp Жыл бұрын

    Все таки не согласен с утверждениями: 1. Запись len(lst) и lst.len(). Есть неписаные общепринятые стандарты, где len, length и size отвечают за количество элементов (int). Либо пример не удачный, что len возвращает строку, либо это просто введение в заблуждение 2. Методы write используются в самом питоне, самый простой пример запись в текстовый файл, а не его запись напрямую в хранилище (если не использовать контекстный менеджер или .save()) with open('file.txt', 'w') as f: f.write("Строка ") И введение в заблуждение происходит только от субъективного предположение что будет.

  • @t0digital

    @t0digital

    Жыл бұрын

    1. "Есть неписаные общепринятые стандарты" Не все им следуют. Никто не мешает создать метод len(), который будет делать совсем не возвращение длины контейнера, и он может быть реализован не в контейнере. А len(x) в питоне всегда вернет int и на входе всегда контейнер. By design нет возможности накосячить, о чем и говорит Гвидо. 2. "Методы write используются в самом питоне" Нет проблемы в методе write, есть проблема в методе write, когда он не пишет в файл или сеть, то есть делает не то, что от него ожидаешь.

  • @NearBirdsamp

    @NearBirdsamp

    Жыл бұрын

    @@t0digital По первому пункту для наглядности можно было использовать класс square, где size вернет, пусть будет tuple(float, float). Тогда да, в этом случае будет действительно наглядно. (Посидел, еще подумал) 2. Не могу вспомнить на своей практике, чтобы write вел себя иначе, чем запись чего-то "В" куда-то. Может есть примеры?

  • @swag4297

    @swag4297

    Жыл бұрын

    тоже с этим не согласен в видео, x.count('п') - понятно, что метод возвращающий количество букв н из строки, если бы в python len был постфиксным было бы все тоже самое и все бы привыкли, не заметив неладного. На уровне языка и то и то реализовано одинаково. Про то, что проще читается согласен. Унификация итерабельных тоже (str[0] и list[0])

  • @d4vlL

    @d4vlL

    Жыл бұрын

    @@t0digital 1. Никто не мешает в дандер методе определить чушь, которая будет неожиданным образом возвращать не len(inner_container), а строку, числовой литерал или чего еще похуже. В итоге by design накосячили. Чяднт? Суть глобальных методов все же не в том, чтобы предотвратить говнокод, а в том, чтобы было удобнее и проще писать кастомные структуры данных, добавлять в язык новые фичи, делать код расширяемым и гибким. Человека, который пишет говнокод, не понимая этого совсем, не остановит дизайн языка. Он придумает способы сделать спагетти из простого кода.

  • @t0digital

    @t0digital

    Жыл бұрын

    Попробуйте реализовать дандер-метод len, возвращающий строку, убедитесь, что интерпретатор это не пропустит и упадёт с TypeError. И хороший линтер тоже это не пропустит. Можно ли написать свою программу нерабочей? Можно, конечно, всегда есть возможность сделать говно. Задача инструмента (Python в этом случае) усложнить способы сделать говно там, где это возможно.

  • @khnykaq8823
    @khnykaq8823 Жыл бұрын

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

  • @fri5tl

    @fri5tl

    10 ай бұрын

    Если совсем занудничать, то во втором случае ОПРЕДЕЛЕНА функция len В то время как глобальная функция len вызывает __len__ объекта И на самом деле это стандартный протокол для глобальных функций типа len next iter

  • @BumatuHe
    @BumatuHe Жыл бұрын

    Не вычислять а нагло без затрат получать;)

  • @nikita-nikita
    @nikita-nikita Жыл бұрын

    Если len возвращает строку, то у автора кода беды, нет? Почему бы тогда не вынести все методы в процедуры? get(keys(dict), 1), красота

  • @t0digital

    @t0digital

    Жыл бұрын

    Да, у автора кода беды, задача в том, чтобы by design не допускать такие беды

  • @user-gs6of5vv6r
    @user-gs6of5vv6r Жыл бұрын

    Несогласен, с автором как по мне все что он сказал по len(x), справедливо и для x.len(). Как по мне самый оптимальный вариант это как в rust с типажами

  • @t0digital

    @t0digital

    Жыл бұрын

    len(x) - вернет всегда int, x всегда контейнер. x.len() - неизвестно что вернёт, неизвестно, что такое x. Можно быть несогласным и с температурой за окном:)

  • @user-gs6of5vv6r

    @user-gs6of5vv6r

    Жыл бұрын

    Ну так типажи решают эту проблему

  • @t0digital

    @t0digital

    Жыл бұрын

    Как типажи запретят реализовать метод len для не контейнера и возвращаеть не int?

  • @user-nf9tj6lb3n

    @user-nf9tj6lb3n

    Жыл бұрын

    @@t0digital это не так, возьмите ваш класс гараж и реализуйте у него дандер метод __len__ как возврат строки «5 яблок». Возвращается не целое число. В принципе, поскольку глобальный len, насколько я помню, просто оборачивает вызов дандер метода __len__, то понятное дело, что этот метод может быть реализован не обязательно у контейнера, и не обязательно возвращающим целое число!)

  • @user-nf9tj6lb3n

    @user-nf9tj6lb3n

    Жыл бұрын

    Приношу извинения, допустил ошибку) Интерпретатор форсит, чтобы __len__ возвращал именно int (можно было бы проговорить это в видосе). Соответственно, никаких строчек "5 яблок" быть не может. Однако, x таки не обязательно контейнер

  • @OlViktorovich
    @OlViktorovich Жыл бұрын

    если посмотреть класс строки - то встроенный str.__len__() просто ссылается на глобальный метод len(), из этого можно сделать вывод, что и метод len() и встроенный str.__len__() сразу лезет в C и особого прироста быстродействия в предпочтении того или этого ... привожу доводы из исходников: class str(object): def __len__(self, *args, **kwargs): # real signature unknown """ Return len(self). """ pass def len(*args, **kwargs): # real signature unknown """ Return the number of items in a container. """ pass

  • @t0digital

    @t0digital

    Жыл бұрын

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

  • @OlViktorovich

    @OlViktorovich

    Жыл бұрын

    @@t0digital погорячился не досмотрев ролик до конца ... но не буду свой комментарий удалять (спасибо за ответ). Вы другой смысл вкладывали ... про стиль кода, и хотя мне и в голову не могло прийти переписывать встроенные методы (перед названием метода сам прежде проверяю нет ли такого встроенного...) И признаю Вы Правы

  • @pokruk0
    @pokruk0 Жыл бұрын

    Максимально не согласен что это как-то помогает читаемости кода. Тем-же макаром в __len__ тоже может вернуться не пойми что

  • @t0digital

    @t0digital

    Жыл бұрын

    Дандер метод может вернуть только int. Ничего больше. То, что он может вернуть неправильный int - ну да, у вас всегда есть возможность написать программу неправильно:)

  • @Sander38rus
    @Sander38rus9 ай бұрын

    Главная претензия у меня к грязным названиям. Почему len вместо length? Неужели так важно было пренебречь 3 последними буквами? Это же неинтуитивно. Почему pow вместо power? str вместо string. Гвидо очевидно переродился из индуса

  • @walterwhite4407
    @walterwhite4407 Жыл бұрын

    йов йов йов йов

  • @LeeSoftRu
    @LeeSoftRu Жыл бұрын

    Суть ролика в том, что Гвидо опирался на рекомендации HCI. Все остальные аргументы уровня «Библия истинна потому, что так сказал Бог. А в Библии написано что Бог есть и верить стоит только ему. Рамен!». Но спасибо за видос, давно мучился этим вопросом и всё ещё не согласен с этим решением.

  • @t0digital

    @t0digital

    Жыл бұрын

    len(x) - вернет всегда int, x всегда контейнер x.len() - неизвестно что вернёт, неизвестно, что такое x С этим можно быть также несогласным как с погодой за окном:) Да, это тоже часть HCI. Весь Python это HCI во многом, благодаря чему это язык номер один сейчас. Потому что синтаксис это пользовательский интерфейс языка программирования

  • @LeeSoftRu

    @LeeSoftRu

    Жыл бұрын

    @@t0digital что вернет len(10)? len(float)?

  • @t0digital

    @t0digital

    Жыл бұрын

    @@LeeSoftRu ошибку, разумеется. Ещё ошибку вернёт код 1/0, код 5() и бесконечно большое множество других идиотизмов.

  • @LeeSoftRu

    @LeeSoftRu

    Жыл бұрын

    @@t0digital Вас панонял. Знакомы [с критическим мышлением вы] не норм.

  • @t0digital

    @t0digital

    Жыл бұрын

    @@LeeSoftRu хорошо, раз панонял)

  • @user-jd4rl7im6d
    @user-jd4rl7im6d Жыл бұрын

    Честно сказать, очень поверхностно, и по-сути так и не говорит, в чем смысл существования глобальной функции len(). Ведь эта функция лишь вызывает магический метод __len___ у объектов. То есть мы можем просто вызывать метод __len__() и жить без глобальной функции. Собственно так ведь это и реализовано в других языках: мы имплементируем интерфейс с каким-то методом и используем этот метод. Тут мы и докопались до истины. В Пайтон нет интерфейсов, механика их работы по-сути эмулируется с помощью дандер-методов и глобальных функций.

  • @t0digital

    @t0digital

    Жыл бұрын

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

  • @user-jd4rl7im6d

    @user-jd4rl7im6d

    Жыл бұрын

    @@t0digital интерфейсы, протоколя, абстрактные классы в Питоне это просто костыли, на уровне языка их не существует.

  • @t0digital

    @t0digital

    Жыл бұрын

    @@user-jd4rl7im6d а, ясненько

  • @zerdox4
    @zerdox4 Жыл бұрын

    автофокус при жестикуляции триггерится, отвлекает слегка

  • @t0digital

    @t0digital

    Жыл бұрын

    Спасибо, да, пофиксим

  • @BumatuHe
    @BumatuHe Жыл бұрын

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

  • @delir0
    @delir0 Жыл бұрын

    10 минут видео, а нормального ответа так и не было: len(T) существует из-за плохого дизайна языка (aka "исторические причины"). Особенно забавно слышать про "не знать как работают кверисеты". len(Model.objects.filter(...)) запусти на выборку из нескольких миллионов толстых объектов и посмотрим, как долго твоё приложение проживёт в проде на незнании ORM. Остальное аргументировать бесполезно, изучи раст и сам поймёшь, что грош цена всем твоим "веским" аргументам.

  • @t0digital

    @t0digital

    Жыл бұрын

    Я знаком с Раст на достаточном уровне для сравнения с Пайтон. Нет, лен не из-за плохого дизайна языка.

  • @shurko
    @shurko Жыл бұрын

    Не согласен с Гвидо вообще ни в чём. Лично для меня лучше всего читается префиксная запись _без скобок_ : len something , либо постфиксная без скобок something .len , а ещё лучше постфиксная без точки something len

  • @maksemuz

    @maksemuz

    Жыл бұрын

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

Келесі