为什么印刷声明不是pythonic?

这个问题在我看来已经有一段时间了(正如我以前的问题所certificate的那样 ):为什么print(x) )比print x更好(被定义为更为pythonic)呢?

对于那些不知道的人来说,在Python 3.0中print语句被改成了函数。 正式文件在PEP 3105中 ,动机是Guido van Rossum的电子邮件 。

对于这些观点我想作一个对比:

  1. 还有其他的操作符,比如我们写成的语句,虽然它们的function实际上是用一个函数__import__
    • 对于初学者来说,操作员print不属于通用的应用逻辑。 对他们来说,这是一个神秘的运营商,这是他们的计划的高潮。 他们期望它看起来不一样。
    • 所有描述基本Python 2.x的初学者书籍现在都保证从第一个例子中被打破 。 当然,语言有时会改变,但是这些改变对新手来说通常不太明显。
    • print的function在应用程序级别上可以被复制,这并不是显而易见的。 例如,有时我想从控制台redirect打印作为模式操作系统对话框。
    • 虽然人们说很难将所有的print语句重写到一个函数中,但是他们已经迫使每个Python 2.x开发人员为他们所有的项目完成这些工作。 好,自动转换器不难。
    • 如果print是一个语句环绕函数__print__那么每个喜欢具有操作函数print的能力的人都可以得到__print__

那么,我们可以请Stack Overflow页面上的这个问题有一个规范的答案吗?

在你看来我是一个辩论,而不是一个问题 – 你真的会接受一个答案,显示你的断言是多么严重和错误吗?!

谈到你的辩论要点:

还有其他的操作符,比如我们写成的语句,虽然它们的function实际上是用一个函数__import__

绝对错误:函数__import__ (就像其他函数和运算符一样)在“调用者”(包含它的代码)范围内没有绑定任何名称 – 任何绑定“调用者范围”中的名字的“thingie”成为一个声明(就像赋值,定义和call )。 你的“观点”看起来完全错过了Python在语句和expression之间的深刻和关键的区别 – 人们可能会不喜欢这种区别,但是忽略它最明显是错误的。

Python语句是Python编译器必须特别注意的事情 – 它们可能会改变名称的绑定,可能会改变控制stream,并且/或者在某些条件下可能需要从生成的字节码中完全删除(后者适用于assert ) 。 print是这个断言在Python 2中唯一的例外; 通过从语句表中删除它,Python 3删除了一个exception,使得一般的断言“只是保持”,因此是一个更常规的语言。 特殊情况不足以打破规则长期以来Pythonic的宗旨(在交互式解释器的>>>提示符下input以显示“Python的Zen”),并且对语言的这种改变消除了对此的违反由于早期的,错误的devise决定而必须保持多年的原则。

对于初学者来说,操作员打印不属于通用的应用逻辑。 对他们来说,这是一个神秘的运营商,这是他们的计划的高潮。 他们期望它看起来不一样。

尽早治愈他们的误解初学者是一件非常好的事情。

所有描述基本Python 2.x的初学者书籍现在都保证从第一个例子中被打破。 当然,语言有时会发生变化,但变化通常对新手来说不太明显。

语言很less以深度和反向不兼容的方式进行改变(Python每10年就会这样做),很less有语言特征对于新手来说是高度可见的,所以观察的总数很less,但即使在这个小小的指南针中,find一些反例,其中一个对初学者来说非常明显的functiondevise得非常糟糕,以至于消除这个function非常值得中断。 例如,基本的现代方言,如微软的Visual Basic,并没有使用明确的用户input行号,这是一个“特点”,因为它在Basic的早期方言中是强制性的,所以对所有人来说都是可怕的和高度可见的。 Lisp的现代变体(从Scheme开始)不使用dynamic范围,这是一种令人伤心的非常明显的错误(通常performance为代码中难以理解的错误),基本上只要他们开始在Lisp中编写函数1.5(我曾经是一个初学者,可以certificate它有多糟糕)。

打印的function在应用程序级别上可以被复制,这并不是显而易见的。 例如,有时我想从控制台redirect打印作为模式操作系统对话框。

不知道我遵循这个“点”。 只需将sys.stdout更改为您最喜欢的伪文件对象并将其redirect到您的内容即可 – 您可以select使用内置函数print (Python 2中没有的),但是没有人会扭曲你的arm并强制你这样做。

虽然人们说很难将所有的打印语句重写到一个函数中,但是他们已经迫使每个Python 2.x开发人员为他们所有的项目完成这些工作。 好,自动转换器不难。

2to3工具的确可以处理所有这些容易的表面不兼容问题 – 没有任何汗水(除了print之外,还需要运行多余的东西来处理,所以人们广泛使用)。 那么,你在这里的“重点”是什么?

如果打印是一个语句打包function打印,那么每个喜欢具有操作function打印function的人都可以得到很好的服务。

这样的安排本身不会去除一个不必要的关键字(特别是一个不合理的不规范 ,正如我上面所解释的那样:一个没有充分理由作为陈述的陈述,因为绝对不需要编译器意识到它在任何方式,形状,或forms!)。 对于我来说,拥有这样一个底层函数将会增加任何真正的价值还不是很清楚,但是如果你有真正的用例,那么你肯定可以在Python Ideas邮件列表中提出这样一个例子 – 这样一个底层函数,如果被certificate是非常珍贵的,可以对Python 2.7中的print语句以及Python 3.2中的print函数进行改进。

但是,考虑一个典型情况,可能需要对内置print进行猴子打补丁:添加关键字参数以允许进行精细的调整。 你明显提出的__print__函数如何从__print__语句中得到KW参数? 一些比>> myfile和尾随逗号更恐怖的语法…?! 与print作为一个函数,关键字参数遵循只适用于每个函数和函数调用完美正常和普通规则 – 幸福!

因此,总而言之, print是一个函数,因为它消除了exception,特殊情况以及对奇怪的特殊语法的任何需求–Python的商标是简单,规则和一致的。

这是我讨厌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,) 

Shudder,或者使用sys.stdout.write ,这几乎和cddgy差不多,因为它和print有非常不同的行为。 它也看起来不同,这意味着我几乎永远不会记得它存在。

在一个短的一次性types的设施中使用print语句,然后改进它来使用日志logging或更好的东西只是不雅观。 如果打印工作像这样的事情,特别是可以用于高阶函数,那么当你不使用真正的日志logging或真正的debugging器,它会比你使用的东西更好。

print语句还包含用于打印到特定文件的不寻常的>>语法。 Python中没有其他语句具有这种语法,所以在这种情况下是不寻常的。

我相信你是对的,但是print语句的大部分问题都可以通过引入__print__函数来解决。

我发现GvR的“打印是唯一的应用程序级别的function,有专门的声明”令人信服。 Python是一种通用的语言,不应该有一个语句作为操作符或关键字输出到stream中。

这不是pythonic,因为语法应该是:

 stdout.append("Hello World") 

要么

 stdout += "hello world" 

免责声明:我真的很喜欢Python。

在一个严肃的笔记…

我认为Python的对象模型和“实现它自己”的方法,如属性可见性是很好的。 我认为这个OOP的“一切都是对象”的方法,甚至定义为对象结构集合的对象都是非常清晰的。

我担心Python会做的就是成为一种语言,不能以一种明确的方式expression它的意图……我不愿意看到这些原则的美妙陷入过度思考已经非常规的语法expression。 有点像Lisp ,漂亮的结构,严酷的语法。