2

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

以这段代码为例:

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()

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

输入图像的基本路径:未输入路径


按 ENTER 退出

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

当代码更改为此

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()

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

输入图像的基本路径:c:\
C:\


按 ENTER 退出

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

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

4

2 回答 2

5

您正在看到行缓冲的效果。首先刷新stdoutsys.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行实际上毫无意义)。在 Python 3 中,I/O 已经过彻底检查,stdout缓冲语义也发生了微妙的变化。在 Python 2 中,sys.stdin.readline()调用会自动刷新stdout,在 Python 3 中不再是这种情况。

如果您使用该input()函数而不是直接读取stdin,则根本不需要刷新:

msg = 'Enter the base path of the images: '
try:
    # python 2
    path = raw_input(msg)
except NameError:
    # python 3
    path = input(msg)
于 2013-02-01T13:03:11.537 回答
2

在这种情况下,我会检查我的 python 版本并替换适当的“输入”函数:现在你可以在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()
于 2013-02-01T13:09:20.100 回答