Почему утверждение print не является pythonic? - программирование
Подтвердить что ты не робот

Почему утверждение print не является pythonic?

Этот вопрос довольно долго меня прослушивал (о чем свидетельствует мой предыдущий вопрос): почему именно print(x) лучше (который определяется как более пифонический), чем print x?

Для тех, кто не знает, оператор print был изменен на функцию в Python 3.0. Официальная документация находится в PEP 3105, а мотивация находится в Guido van Rossum по электронной почте.

В те моменты я хотел бы сделать контрапункт:

  • Существуют и другие операторы, такие как import, которые мы пишем как оператор, хотя их функциональность фактически дублируется с помощью функции __import__
    • Для новичков оператор print не относится к общей логике приложения. Для них это таинственный оператор, который является кульминацией их программы. Они ожидают, что он будет выглядеть по-другому.
    • Теперь все начинающие книги, описывающие базовый Python 2.x, гарантированно будут разбиты с первого примера. Конечно, языки иногда меняются, но эти изменения обычно менее заметны для новичков.
    • Мне сразу не кажется очевидным, что функциональность print можно дублировать на уровне приложения. Например, иногда я хотел бы перенаправить печать с консоли в виде модального диалогового окна ОС.
    • В то время как люди говорят, что сложно переписать все операторы print в функцию, они заставили каждого разработчика Python 2.x делать именно это для всех своих проектов. Хорошо, это не сложно с автоматическим преобразователем.
    • Каждый, кому нравится иметь возможность манипулировать функцией print, будет столь же хорошо обслуживаться, если print - это функция обертки оператора __print__.

Итак, можем ли мы ответить каноническим ответом на этот вопрос на страницах?

4b9b3361

Ответ 1

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

В поле для обсуждения:

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

Абсолютно неправильно: функция __import__ (например, каждая другая функция - и оператор, если на то пошло) связывает имена no в области "вызывающего" (код содержащее его) - любая "вещь", которая связывает имена в "области вызова" должна быть оператором (точно так же, как назначение, def и call). Ваша "точка", похоже, полностью пропустила чрезвычайно глубокое и важное различие, которое Python рисует между утверждениями и выражениями - можно разумно не любить это различие, но игнорировать его, очевидно, просто неправильно.

Операторы Python - это то, о чем должен знать специальный компилятор Python - они могут изменять привязку имен, могут изменять поток управления и/или могут быть полностью удалены из сгенерированного байт-кода в определенных условиях (последнее применяется до assert). print был исключением только для этого утверждения в Python 2; удалив его из списка утверждений, Python 3 удаляет исключение, делает общее утверждение "просто удержанием" и, следовательно, является более регулярным языком. Специальные случаи не являются достаточно сложными, чтобы нарушать правила. уже давно является питоновским принципом (do import this в приглашении интерактивного интерпретатора >>>, чтобы увидеть "Zen of Python" ), и это изменение к языку устраняет нарушение этого принципа, который должен был оставаться на протяжении многих лет из-за раннего ошибочного дизайнерского решения.

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

Лечение начинающих их заблуждений как можно раньше - очень хорошая вещь.

Все начинающие книги, которые были описание базового Python 2.x теперь гарантированно быть сломанным из кулака пример. Конечно, языки иногда меняются, но изменения обычно менее заметны для новичков.

Языки редко меняются глубоко и обратно-несовместимыми способами (Python делает это примерно раз в десять лет), и некоторые особенности языка "очень заметны для новичков", поэтому общее количество наблюдений невелико, но даже внутри этого крошечного компаса мы можем легко найти встречные примеры, где функция, очень заметная для новичков, была настолько плохо спроектирована, что ее удаление было достойным разрушения. Например, современные диалекты Basic, такие как Microsoft Visual Basic, не используют явно введенные пользователем номера строк, "особенность", которая была ужасной и очень заметной для всех, поскольку она была обязательной в ранних диалектах Basic. Современные варианты Lisp (начиная с Схемы и далее) не используют динамическое масштабирование, что было очень печально, как правило, проявлялось как плохо понимаемое в коде, как обычно, для начинающих, в основном, как только они начали писать функции в Lisp 1.5 (я когда-то был новичком в этом и мог засвидетельствовать, насколько это сильно меня укусило).

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

Не уверен, что я следую этой "точке". Просто измените sys.stdout на ваш любимый псевдо файл и перенаправляйте его на содержимое вашего сердца - у вас есть возможность обезглавливать встроенную функцию print (которой у вас никогда не было на Python 2), но никто не скручивает вашу руку и заставляя вас это делать.

Пока люди говорят, что переписать все операторы печати для функции, они заставили каждого Python 2.x разработчик сделать именно это для всех их проектов. Хорошо, это не сложно с автоматическим преобразователем.

Инструмент 2to3 действительно заботится обо всех таких простых поверхностных несовместимостях - без пота (и он должен быть запущен в любом случае, чтобы позаботиться о еще нескольких, кроме print, поэтому люди действительно его используют), Итак, что вы здесь делаете?

Каждый, кто обладает способностью для управления печатью функции будет так же хорошо, как если бы печать была печать.

Такое соглашение само по себе не удалит ненужное ключевое слово (и, самое главное, неоправданную нерегулярность, как я объяснил выше: выражение, в котором нет хорошо причина для be утверждения, потому что совершенно не нужно, чтобы компилятор специально знал об этом каким-либо образом, формой или формой!). Мне совершенно не ясно, что такая базовая функция добавит какую-либо реальную ценность, но если у вас есть реальные варианты использования, вы можете, конечно, предложить этот случай в списке рассылки Python Ideas - такая базовая функция, если окажется, что она действительно драгоценна, может быть модифицирован для использования оператором print в Python 2.7, а также функцией print в Python 3.2.

Однако рассмотрим типичный случай, когда вы захотите обезглавить встроенный print: добавление аргументов ключевого слова, чтобы позволить причудливые настройки. Как бы функция __print__, которую вы, по-видимому, предложили, когда-либо задавали те аргументы KW из инструкции __print__? Какой-то более забавный синтаксис, чем ужасы >> myfile и конечная запятая...?! С print как функция аргументы ключевого слова следуют только совершенно нормальным и обычным правилам, которые применяются к каждой функции и вызову функции - блаженству!

Итак, в целом, это больше Pythonic для print, чтобы быть функцией, потому что он устраняет аномалии, особые случаи и любую потребность в странном исключительном синтаксисе - простота, регулярность и единообразие - это торговая марка Python.

Ответ 2

Вот причина, по которой я ненавижу утверждение print в 2.x.

>>> something()
<something instance at 0xdeadbeef>
>>> print something()
<something instance at 0xdeadbeef>

бесполезный объект не имеет полезного __str__, отлично, я могу справиться, посмотреть на него еще немного.

>>> dir(something())
['foo', 'bar', 'baz', 'wonderful']
>>> help(something().foo)
"foo(self, callable)"

hmm.. так ли это вызываемые аргументы?

>>> something().foo(print)
    something().foo(print)
                        ^
SyntaxError: invalid syntax
>>> something().foo(lambda *args: print(*args))
    something().foo(lambda *args: print(*args))
                                      ^
SyntaxError: invalid syntax

Итак... Мне нужно либо определить функцию для использования

>>> def myPrint(*args): print *args
    def myPrint(*args): print *args
                              ^
SyntaxError: invalid syntax
>>> def myPrint(*args): print args
...
>>> myPrint(1)
(1,)

Shudder, или используйте sys.stdout.write, который почти такой же cludgy, так как он имеет совсем другое поведение от print. Это также выглядит по-другому, что означает, что я почти никогда не забуду, что он существует.

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

Ответ 3

Оператор print также содержит необычный синтаксис >> для печати в конкретном файле. В Python нет другого выражения, имеющего этот синтаксис, поэтому это необычно.

Я считаю, что вы правы, но большинство проблем с оператором print можно было решить путем введения функции __print__.

Ответ 4

Я обнаружил, что GvR "печать - это единственная функциональность на уровне приложения, которая имеет для нее инструкцию, убедительную. Python является языком общего назначения и не должен иметь оператора вывода для потока в качестве оператора или ключевого слова.

Ответ 5

Это не pythonic, потому что синтаксис должен быть:

stdout.append("Hello World")

или

stdout += "hello world"

Отказ от ответственности: мне нравится Python.

На серьезной ноте...

Я думаю, что объектная модель Python и подход "Реализовать сами" для таких вещей, как видимость атрибутов, велики. Я думаю, что этот подход "все является объектом" для ООП, и даже объекты, определенные как совокупность объектов, очень понятны.

Чего я опасаюсь, Python будет делать, это язык, который не представляет намерений ясным образом... и я бы не хотел, чтобы красота принципов увязла в чрезмерном рассмотрении уже нетрадиционного синтаксического представления, Похоже на Lisp, красивая в ней структура, мрачная, imho в ней синтаксис.