Pull to refresh

Comments 69

UFO just landed and posted this here
Потому что это не присваивание, а именование выражения. То есть само вычисление происходит не в том месте, где стоит :=, а позже, где новое имя используется.

Это не := из Pascal. Поэтому в стандарте PEP-572 столько места уделено визуальному отделению := от = с помощью тех самых скобок, чтобы избежать ошибочного использования одного оператора вместо другого.

Погодите, но если это не присваивание, а именование выражения, то зачем его вообще писать в скобках?


match1 := pattern1.match(data)
match2 := pattern2.match(data)
if match1:
    result = match1.group(1)
elif match2:
    result = match2.group(2)
else:
    result = None

Чем вот такой вариант не вариант? Или это всё же присваивание, раз уж оно называется Assignment Expressions?

т.е. некоторые пишут так
group = re.match(data).group(1) if re.match(data) else None
хотя это делает программу медленнее (а кому какое дело)
другие так не пишут, т.к. громоздко (серьёзно?)
и теперь для этих других придумали сахарок?
group = match.group(1) if (match := re.match(data)) else None
[facepalm]
В чем проблема сахара? (причем я не шарю, думаю тут не просто сахар)

Или вы из разряда «не страдал — не мужик»?

проблема, что решается не упомянутая вскользь неэффективность приведённой в пример идиомы, а только сокращается её запись, делая неэффективность ещё менее очевидной, якобы, чтобы большему количеству разработчиков было удобнее писать такой неэффективный код

Разве во втором случае метод match(data) выполняется не один раз вместо двух в первом? Я думал в этом идея.
Разве во втором случае метод match(data) выполняется не один раз вместо двух в первом? Я думал в этом идея.
да, Вы правы, должно быть одно вычисление
смутила формулировка ответа asorkin:
Потому что это не присваивание, а именование выражения. То есть само вычисление происходит не в том месте, где стоит :=, а позже, где новое имя используется.
это неверно, вычисление будет сразу, это не алиас на выражение, а алиас на результат выражения, где под выражением для := и = подразумевается разный скоуп, поэтому введена синтаксическая разница записи
Я бы сказал что это одновременно присваивание и выполнение, так проще понимается. На самом деле неплохой сахар чтобы не писать присвоение выше как переменную которую придется использовать.
Синтаксис этого оператора запрещает использовать его без скобок, чтобы он не заменял ´=´ при обычном использовании
Может писать так легче, но читать — сложнее.
Как бы вроде бы парадигма питона была — читаемость, не?
Кажися идем в сторону современной джава…

Согласен. После этого кипиша (PEP-572) Гвидо и ушёл с поста BDFL — не было больше сил и нервов противостоять сообществу.

UFO just landed and posted this here

Зато, становится намного более понятно, с чем работает каждая функция, какой тип принимает, какой возвращает. С ними можно прикрутить статический анализатор (mypy), использовать их для сериализации (pydantic), задавать ими форматы данных для API (fastapi).

UFO just landed and posted this here
С учетом того, что аннотация преимущественно только на аргументах функции и возврате, то особо не загромождает.
UFO just landed and posted this here

Если заменить в тексте Python на C++, то получим тот же самый вывод) Раньше трава была зеленее)

Так никто аннотации типов использовать не заставляет. Но мне с ними, например, код проще и писать, и читать. Это вот «передадим кучку объектов какого-то там типа» меня всегда в Питоне выстёгивало. Поди разберись, не читая код метода, что передавать и что получим в результате. А тут сразу всё ясно.
Круче было бы, конечно, со строгой типизацией, но и с имеющейся рантайм-проверкой типов уже можно жить.
UFO just landed and posted this here

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

Если сильно не увлекаться и использовать только там, где «две строчки в одну», то вроде бы вполне читабельно. Ну и может в самом деле некоторый плюс в производительность можно будет получить, хотя как-то сомнительно звучит.

Читаемость — весьма субъективное понятие. Там, где джун будет вникать в код, сеньор видя знакомый паттерн уже знает, что и куда писать. А нужно ли делать код понятный всем? Это хоть и часть парадигмы питона, но совсем не значит, что парадигма не может меняться или что все в питоне должно следовать правилам, придуманным целую эпоху назад.


Я вот, например, люблю высокую плотность экшена в коде, а инициализация/присваиваение перед условием вызывает только раздражение и непонимание, зачем знакомый паттерн нужно переписывать миллионы раз в одних и тех же ситуациях.
А то, что использование оператора может превратиться в изврат — другой вопрос. Любой инструмент можно использовать неправильно, это же не повод отказываться от удобных инструментов.
Тот же map может очень органично вписаться в код или стать пыткой. Не выкидывать же его из питона теперь.
Ну и я считаю, что такие вещи, как := это удел опытных программистов, которые хотят вложить больше смысла в меньшее количество кода. И начинать его использовать надо только тогда, когда почувствуется острая необходимость

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

Читаемость — весьма субъективное понятие
Быть может до определенного момента. Любая конструкция имеющая вложенное содержимое локализуемое посредством скобок любого формата по умолчанию заставляет парсить глазами этот текст, ухудшая читаемость.
Дело не столько в читаемости, сколько в побочных эффектах в выражениях, которые некоторые захотят использовать, чтобы урвать пару строк код, а в итоге получится такое безобразие, что мало не покажется никому.

Пока не получается перейти: в python 3.8 поломали API сишных расширений, из-за этого не собирается cython, который во многих библиотеках используется. Конечно, в версии из гита уже поправили, но на pypi ещё не загрузили.

Там некоторые экспорты забыли добавить в Python.dll.

Прежде всего, дело в том, что изменили сигнатуры некоторых функций. В частности, cython при компиляции жалуется на изменение PyCode_New в CPython.

UFO just landed and posted this here
UFO just landed and posted this here
Поддерживаю. Что будет дальше? Введут таки какие-нибудь многострочные лямбды, добавив особый синтаксис, отличный от имеющегося?

Вариант с as рассматривали и отклонили: https://www.python.org/dev/peps/pep-0572/#alternative-spellings.
Если вкратце: не хотели добавлять лишнюю семантику. В рассматриваемых случаях, переменная с правой стороны от as всегда присутствует в области видимости:


  1. import x.y.z as z
    # z = x.y.z
  2. with context as c:
    # c = context.__enter__()
UFO just landed and posted this here

Имеется ввиду, "не хотели добавлять новую семантику оператору as".

UFO just landed and posted this here
UFO just landed and posted this here
Опять код написанный на Python 3.8 не будет запускаться на младших версиях?

Я не хейтер, просто искренне интересуюсь.

А какой язык вообще поддерживает такой вид совместимости?

Пишу на Go, он декларирует (и выполняет) совместимость в версии 1 уже много лет.

Да ладно? Вон версия 1.10 позволяет писать x[1.0 << s], в то время как в более ранних такой код не скомпилируется.

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

Может быть есть еще примеры, более ощутимые, так сказать?

Ну вот в 1.5 было более ощутимое изменение.


Что же до его давности — это лишь означает что сам язык не развивается. Невозможно одновременно развивать язык и поддерживать как прямую так и обратную совместимость.

Вообще не представляю совместимости «в низ» — старшая версия всегда добавляет новые фитчи, которые не доступны младшей версии.
Совместимость «в верх» (в старшей версии работает код младшей) это еще куда не шло. Такое вроде must have, и даже периодически варнинги интерпретатор выплевывает "...was deprecated'
Ну например, я могу скомпилировать код с помощью java11 и полученный байт-код может исполняться на 1.6. Обратная совместимость на уровне синтаксиса и на уровне байт-кода разные вещи, вторую можно попробовать и обеспечить.

А вот не факт. Лямбды сделаны через invokedynamic, а indy только в 1.7 появилась же.

Ну в java там вообще есть куча настроек и заморочек на эту тему.

Ну, так просто в байт-кода своя версионность и это не считается за пример :D Если в байт-коде поменяют версию с 1.1 до 1.2, то очевидно команды из 1.2 не будут исполняться на старых версиях JVM.

Ну в данном случае я могу один и тот же исходный код скомпилировать в обе версии байт-кода и поставлять тут версию, которая нужна пользователю, а в питоне не факт что исходник транслируемый в байт-код для py3, получиться оттранслировать в байт-код для py2.
Ну в питоне нет ни совместимости вверх ни совместимости вниз, иначе бы не пришлось бы придумывать pip vs pip3 и все эти virtualenv Просто стало интересно неужели в каждой минорная цифре Python 3.x вводятся breakable changes. Как вы там живете вообще? Судя по реакции на безобидный вопрос, не очень.

Обратная совместимость в Питоне, вообще-то, есть. Надо просто считать python 2 и python 3 двумя разными языками.


virtualenv, кстати, в go тоже есть и аж двух разных видов (legacy GOPATH и go modules)

Жаль что авторы блогов и составители документации не следуют этому замечательному совету. Но видимо есть причина этому.

Есть ли гарантия какую версию выдаст команда python --version на произвольной системе? Вот у меня сейчас пишет Python 2.7.15+, а если я удалю Python 3.x у будет ли выпадать сообщение об ошибке или запустится 3.x? Есть сомнения.

go modules решают в первую очередь проблему breaking changes в библиотеках, то что они фиксируют версию языка — побочный результат, ибо проблема постоянного изменения синтаксиса языка в go не актуальна.

Ну так virtualenv тоже делался именно для решения проблемы breaking changes в библиотеках. То что его можно использовать для фиксации версии самого python я до вашего комментария как-то даже и не думал...

UFO just landed and posted this here

Зато в 3.5 добавили ключевых слов, отчего ЕМНИП paramico поломался из-за параметра с названием async

Питон идет в сторону усложнения.Это хорошо или плохо?
Не видел ни одного языка, который шёл бы в сторону упрощения. Ну, по крайней мере из широко используемых. Тут хотя бы никто не заставляет использовать все эти новые особенности.

Это сарказм что ли? move semantics, variadic templates, вычисления времени компиляции, ranges, ещё больше особо шаблонной магии и т.д. Где тут упрощение то? То, во что превращается C++, который никогда простым и не был, это не упрощение, это вырождение в некоторое новое подмножество языка. И если использовать только его, то в некоторых случаях код получится проще и лаконичнее, но далеко не всегда.


И подобные статьи этому подтверждение:
https://habr.com/ru/company/jugru/blog/469465/


А вот, например, ликбез о том как же правильно передавать аргументы в конструктор в современном C++
https://habr.com/ru/post/460955/


А вот этот список так вообще доставляет.
https://en.cppreference.com/w/cpp/compiler_support


Ну и "спор" на лоре о размере стандарта C++
https://www.linux.org.ru/forum/development/14796243

Я просто выразил опасение, что Python движется возможно не туда (как и С++) — в неконтролируемое расширение. Но кое-что интересное почитать из вашего ответа я для себя нашел.

Так и я тоже считаю, что Python идёт куда-то не туда :)
Вся эта эмуляция типизации, особенно с генериками выглядит чужеродно в питонокоде. Одно дело — аннотировать сигнатуру функции и некоторые переменные для подсказок в IDE и самодокументации кода и совсем другое, когда из динамической типизации пытаются сделать статическую с помощью тайпхинтов и mypy.


Кстати, пока писал комментарий про C++, потерял одну ссылку, вот она:
https://habr.com/ru/company/jugru/blog/438260/

Кто в теме, подскажите! В Kotlin есть очень удобная вещь, называемая «безопасные вызовы», позволяющая не писать проверку на null для цепочки вызовов, а просто использовать конструкцию вида: «bob?.department?.head?.name». Если одно из свойств имеет значение null, то вся цепочка вернет null. Планируется ли добавить подобный функционал в Python?
В источнике:
Added an = specifier to f-strings. An f-string such as f'{expr=}' will expand to the text of the expression, an equal sign, then the representation of the evaluated expression.

В англоязычном рекламном посте превращается в:
did you notice = after chr(65)? this does the trick. It helps as to provide a short way of printing variables using f-strings

И наконец мутирует в это:
Заметили это, после chr(65)? Тот самый фокус. Он помогает обеспечить укороченный способ печати переменных с помощью f-строк.


<sarcasm>
Вот это все вызывает просто непреодалимое желание записаться на ваши чудесные курсы по Python. Как минимум вы приучите читать доки, а не статейки в интернете читать.
</sarcasm>
Sign up to leave a comment.