为什么/如何内置Python打印允许“>>”运营商?

时间:2013-09-16 21:13:37

标签: python operators operator-overloading built-in

我搜索过,无法在本网站或其他地方找到答案(总是挑战搜索涉及标点字符的主题)。

我正在查找Python标准库中的StringIOhere),其中一个例子就是这个(摘录):

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 个答案:

答案 0 :(得分:5)

这真的是一个问题。


首先,“如何”问题:

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

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

......语义是:

  

此表单有时称为“print chevron”。在此表单中,>>之后的第一个表达式必须求值为“类文件”对象,特别是具有{{1}的对象如上所述的方法。使用此扩展形式,后续表达式将打印到此文件对象。


第二,“为什么”的问题:

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

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

它在3.0中删除;你只是在看它,因为你使用的是旧版本。

但是,如果您想在2.7中使用新的write()功能,则可以使用future statementprint。但那当然会打破from __future__ import print_function;你必须把它重写为print >>foo, spam

答案 1 :(得分: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 grammar明确允许扩展语法的结果:

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

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

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

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

答案 2 :(得分:2)

在Python 2中,print是一个语句(不是函数),语句可以构成他们喜欢的任何傻瓜语法;-) >>这里与右移运算符无关 - 这是print声明特有的噱头。

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

答案 3 :(得分:1)

您的问题已在duplicate post中得到解答。 引用:

  

print也有一个扩展形式,由第二部分定义   语法如上所述。这种形式有时被称为“印刷品”   chevron。“在这种形式下,&gt;&gt;之后的第一个表达式。必须   评估为“类文件”对象,特别是具有   write()方法如上所述。有了这种扩展形式,   后续表达式将打印到此文件对象。如果是第一个   表达式求值为None,然后sys.stdout用作文件   输出