Почему оператор print не является pythonic?[закрыто]

StackOverflow https://stackoverflow.com/questions/1053849

  •  20-08-2019
  •  | 
  •  

Вопрос

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

Для тех, кто не знает, print оператор был преобразован в функцию в Python 3.0.Официальная документация находится в БОДРОСТЬ ДУХА 3105 и мотивация заключается в Электронное письмо Гвидо ван Россума.

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

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

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

Это было полезно?

Решение

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

Перейдем к вашим дискуссионным моментам:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Другие советы

Вот причина, по которой я ненавижу инструкцию 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)"

хм..итак, принимает ли этот вызываемый параметр аргументы?

>>> 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,)

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

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

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

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

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

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

stdout.append("Hello World")

или

stdout += "hello world"

Отказ от ответственности:Мне действительно нравится Python.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top