为什么在Python 2.7中自愿使用印刷括号?


98

在Python 2.7中,以下两者将执行相同的操作

print("Hello, World!") # Prints "Hello, World!"

print "Hello, World!" # Prints "Hello, World!"

但是以下内容不会

print("Hello,", "World!") # Prints the tuple: ("Hello,", "World!")

print "Hello,", "World!" # Prints the words "Hello, World!"

在Python 3.x中,括号print是强制性的,本质上使其成为一个函数,但是在2.7中,两者都可以使用不同的结果。我print在Python 2.7中还应该了解什么?


7
在Python 2.x print中,实际上是一个特殊的语句,而不是一个函数。这也是为什么不能像这样使用它的原因:lambda x: print x请注意,(expr)它不会创建元组(结果为expr),但,会创建。

我假设打印的功能和打印支持的语句是保持与旧版本的Python的向后兼容性,同时鼓励人们使用新的语法来对Python 3的迁移
GWW

11
ps,要在2.7中启用打印功能(并且不具有打印语句行为),则必须进行以后的导入:from __future__ import print_function
Jeff Mercado

第二个示例是否将实际上显示“ Hello,World!”?(没有空格)还是打印“你好,世界!” (带有空格),如示例中所示。
kapad

Answers:


106

在Python 2.x print中,实际上是一个特殊的语句,而不是一个函数*。

这也是为什么不能像这样使用的原因: lambda x: print x

请注意,(expr)它不会创建元组(结果为expr),但,会创建。在方寸之间这种可能的结果print (x),并print (x, y)在Python 2.7

(1)   # 1 -- no tuple Mister!
(1,)  # (1,)
(1,2) # (1, 2)
1,2   # 1 2 -- no tuple and no parenthesis :) [See below for print caveat.]

但是,由于print是Python 2.x中的特殊语法语句/语法构造,因此,如果没有括号,它将,以特殊方式处理,并且不会创建元组。对print语句的这种特殊处理使它无论是否有尾随都可以采取不同的行动,

快乐的编码。


* printPython 2中的此行为可以更改为Python 3:

from __future__ import print_function

3
感谢您的(expr) != tuple解释:-)
Hubro 2011年

5

这一切都非常简单,与向前或向后兼容性无关。

print在版本3之前的所有Python版本中,该语句的一般形式为:

print expr1, expr2, ... exprn

(依次对每个表达式求值,将其转换为字符串并在它们之间显示一个空格。)

但是请记住,在表达式周围加上括号仍然是相同的表达式。

因此,您也可以这样写:

print (expr1), (expr2), ... (expr3)

这与调用函数无关。


这是一个完全正确的答案,我不确定为什么它也被否决了。
马丁·彼得斯

这不是关于print (expr1), (expr2), ... (expr3),而是关于为什么print (expr1, expr2, ... , expr3)在python 2.x中是合法的,但它不符合2.x标准。
vinnief '17

5

在谈到UTF-8时,我们有一个有趣的副作用。

>> greek = dict( dog="σκύλος", cat="γάτα" )
>> print greek['dog'], greek['cat']
σκύλος γάτα
>> print (greek['dog'], greek['cat'])
('\xcf\x83\xce\xba\xcf\x8d\xce\xbb\xce\xbf\xcf\x82', '\xce\xb3\xce\xac\xcf\x84\xce\xb1')

最后打印的是带有十六进制字节值的元组。


7
我认为这是因为print可以正确打印UTF-8,但是当它接收到一个元组时,就像您上一次打印的那样,它就repr在其上运行,这时它可能会将dict中的所有字符串编码为ASCII。
Hubro 2012年

3
@Codemonkey,您对repr是正确的。您对ASCII错误。ASCII是Python的默认编码。但是我刚开始使用Python脚本#encoding=utf-8linux env LANG=en_US.UTF-8。因此,repr不会使用默认的ASCII编码,而是使用utf-8编码。
卡洛·史密德

1
Repr str使用特殊string_escape编码进行编码。该字符串已被Unicode编码为UTF-8。
tzot 2014年

@KarloSmid:我想说的是,repr可能采取措施,以确保文本可以通过ASCII代表(通过转义非ASCII符号来),不一定是字符串编码为ASCII。我仍然不知道这是否完全正确。
Hubro

所有 Python容器(列表,字典,元组,集合)repr()在转换为字符串时都包含其内容作为输出(它们不实现__str__,仅__repr__)。您所看到的对UTF-8并不特殊;该repr()字符串为您提供了有效的Python字符串常量是ASCII安全的。
马丁·彼得斯

2

基本上在Python 3之前的Python中,print是一个特殊的语句,如果作为参数获取,则打印所有字符串。因此,print "foo","bar"仅表示“先打印'foo',再打印'bar'”。这样做的问题是,很容易将print当作一个函数来使用,而Python语法对此却模棱两可,因为它(a,b)是一个包含ab只是foo(a,b)对两个参数的函数的调用的元组。

因此,他们对3进行了不兼容的更改,以减少程序的歧义性和规则性。

(实际上,我认为2.7的行为与2.6的行为相同,但我不确定。)


不,并不是“诱人”将其用作功能。:)但是,不可能将其用作函数,因此,例如,您无法[在列表中为x打印x]。
Lennart Regebro
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.