Python 3中__future__模块中print_function的奇怪行为

时间:2013-02-01 12:57:37

标签: python python-import

我在Python 3.2中观察到__future__模块print_function的奇怪行为。

以此代码为例:

from __future__ import print_function
import sys

print('Enter the base path of the images: ', end='')
path = sys.stdin.readline().strip().strip('"')
if len(path) == 0:
    print("No path entered")
else:
    print(root)
print("\n\nPress ENTER to exit")
exit = sys.stdin.readline()

当脚本运行时,控制台会在显示第一个print语句之前等待用户按 ENTER 。 然后输出如下:


Enter the base path of the images: No path entered


Press ENTER to exit

不用说,向用户显示空提示会导致很多混乱,特别是因为很多人都害怕带有白色文本的黑色窗口(命令提示符)。

当代码更改为此

from __future__ import print_function
import sys

print('\nEnter the base path of the images: ', end='') #line now starts with \n
path = sys.stdin.readline().strip().strip('"')
if len(path) == 0:
    print("No path entered")
else:
    print(path)
print("\n\nPress ENTER to exit")
exit = sys.stdin.readline()

然后输出符合预期(假设我们忽略前面的空行):


Enter the base path of the images: c:\
c:\


Press ENTER to exit

当代码在python 2.6中运行时,第一个按预期工作(即在等待接收输入之前显示Enter the base path of the images: )。

这引出我问:
为什么我需要在print函数之前加上\n才能在Python 3.2中显示输出,而在Python 2.6中运行时我不需要\n? /> 可能是print_function在两个版本中的实现方式不同吗?

2 个答案:

答案 0 :(得分:5)

您正在看到线缓冲的效果。首先刷新stdout(使用sys.stdout.flush()向后兼容Python 2):

print('Enter the base path of the images: ', end='')
sys.stdout.flush()

Python 2中的print()函数肯定不同于Python 3中的from __future__ import print_function函数(其中stdout行实际上没有意义)。在Python 3中,I / O已经过大修,sys.stdin.readline()缓冲语义已经巧妙地改变了。在Python 2中,stdout调用自动刷新input(),在Python 3中不再是这种情况。

如果您使用stdin函数而不是直接从msg = 'Enter the base path of the images: ' try: # python 2 path = raw_input(msg) except NameError: # python 3 path = input(msg) 读取,则根本不需要刷新:

{{1}}

答案 1 :(得分:2)

在这种情况下,我会检查我的python版本并替换相应的“input”函数: 现在,只需在用户交互的任何地方使用input即可。

from __future__ import print_function
import sys

if sys.version_info < (3,):
    input = raw_input

path = input('Enter the base path of the images> ').strip().strip('"')
if len(path) == 0:
    print("No path entered")
else:
    print(path)

print("\n\nPress ENTER to exit")
exit = input()