1

我四处搜索,在这个网站或其他地方都找不到答案(搜索涉及标点符号的主题总是一个挑战)。

StringIO我在 Python 标准库(这里)中查找,其中一个例子是这个(摘录):

import StringIO

output = StringIO.StringIO()
output.write('First line.\n')
print >>output, 'Second line.'  # <-- This is the line I'm asking about

操作员如何或为什么在>>这里工作?据我所知(而且我不是 Python 专家),这是正确的移位运算符。我想也许StringIO会覆盖__rshift__或其他东西,但 StringIO 的来源并没有背叛任何这样的东西。

我还没有四处看看print内置是如何实现的,但是通过最初的搜索,我无法弄清楚它是如何工作的。任何人?

4

4 回答 4

5

这真的是几个问题合二为一。


首先,“如何”的问题:

令牌在>>这里实际上不是运算符;print它是语句语法的一部分,如此所述。语法是:

print_stmt ::=  "print" ([expression ("," expression)* [","]]
                | ">>" expression [("," expression)+ [","]])

……语义是:

这种形式有时被称为“打印人字形”。在这种形式中,后面的第一个表达式>>必须计算为“类文件”对象,特别是具有上述write()方法的对象。使用此扩展形式,后续表达式将打印到此文件对象。


二、“为什么”问题:

早期,Python 开发人员认为这是一种写入文件的便捷方式。

从那时起,他们添加了stdout 重定向,以及更强大的文件和字符串格式化 API,所以它不再那么有用了。而且,多亏了关键字参数等其他现代特性,以及几十年的思考,他们提出了一种更灵活的方式来设计print为一个完全不需要任何特殊语法的常规函数​​。但是删除它会破坏向后兼容性,因此直到 3.0 才能删除它。

并且在 3.0 中被移除;您仍然可以看到它,因为您使用的是旧版本。

但是,如果您想要print2.7 中的新功能,您可以使用future 语句from __future__ import print_function. 但这当然会破裂print >>foo, spam;您必须将其重写为print(spam, file=foo).

于 2013-09-16T21:15:50.460 回答
2

它是附加语法;编译器>>print语句后查找:

>>> import dis
>>> def print_redirected(fh, msg):
...     print >>fh, msg
... 
>>> dis.dis(print_redirected)
  2           0 LOAD_FAST                0 (fh)
              3 DUP_TOP             
              4 LOAD_FAST                1 (msg)
              7 ROT_TWO             
              8 PRINT_ITEM_TO       
              9 PRINT_NEWLINE_TO    
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        
>>> def print_direct(msg):
...     print msg
... 
>>> dis.dis(print_direct)
  2           0 LOAD_FAST                0 (msg)
              3 PRINT_ITEM          
              4 PRINT_NEWLINE       
              5 LOAD_CONST               0 (None)
              8 RETURN_VALUE        

不同字节码的>>结果;PRINT_ITEM_TO而不是PRINT_ITEM.

这是Python 语法明确允许扩展语法的结果:

print_stmt: 'print' ( [ test (',' test)* [','] ] |
                      '>>' test [ (',' test)+ [','] ] )

编译器绝不会将 解释>>为右移运算符。

用这种语法重定向打印输出很少使用;您可以直接写入文件,或重新分配给sys.stdout。在任何情况下,print都可以使用(更强大的)字符串格式轻松复制语句提供的简单格式选项。

Python 3 的print()函数接受一个file关键字参数来实现相同的功能。

于 2013-09-16T21:15:33.467 回答
2

在 Python 2 中,printis 是一个语句(不是函数),并且语句可以构成他们喜欢的任何愚蠢的语法;-)>>这里与右移位运算符无关 - 它是print语句特定的噱头。

这被广泛认为是丑陋的,并且在 Python 3print中是一个内置函数(而不是语句),并且要指定要打印到的文件,Python 3 会为函数添加一个可选file=参数print()

于 2013-09-16T21:18:38.030 回答
1

您的问题在重复的帖子中得到了回答。引:

print 还具有扩展形式,由上述语法的第二部分定义。这种形式有时被称为“打印人字形”。在这种形式中,>> 之后的第一个表达式必须计算为“类文件”对象,特别是具有上述 write() 方法的对象。使用此扩展形式,后续表达式将打印到此文件对象。如果第一个表达式的计算结果为 None,则 sys.stdout 用作输出文件。

于 2013-09-16T21:17:01.783 回答