我搜索过,无法在本网站或其他地方找到答案(总是挑战搜索涉及标点字符的主题)。
我正在查找Python标准库中的StringIO
(here),其中一个例子就是这个(摘录):
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
内置如何实现,但初步搜索我无法弄清楚它是如何工作的。任何人吗?
答案 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 statement:print
。但那当然会打破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.stdout
。 print
语句提供的简单格式选项可以在任何情况下使用(功能更强大)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用作文件 输出