调用 serve_forever() 时打印语句不起作用?

Print statements not working when serve_forever() is called?

我有以下小 python 脚本到 运行 本地服务器来测试一些 html:

print('opened')

from http.server import HTTPServer, SimpleHTTPRequestHandler

server_address = ('', 8000)
httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)

print("Listening at https://127.0.0.1:8000/ . . .")
httpd.serve_forever()

当我在终端中 运行 时,它会阻止 print 语句:不打印任何内容。但是服务器可以正常工作,我可以在浏览器中转到 localhost:8000 并访问我的 html 文件。但是,如果我注释掉最后一行,即对 serve_forever() 的调用,它将起作用,同时打印 'opened' 和 'Listening at https:127.0.0.1:8000/ . . .'。当然除了它实际上 工作 ,因为现在服务器不是 运行.

我觉得这很令人困惑。前几行在最后一行之前执行。为什么最后一行会导致前面几行不起作用?

Python3 Windows7 是否有人要问,但我怀疑这是否相关。

这可能与 "infamous" 需要 flush 才能使您的打印件正常工作有关!

相关阅读material:


因为您使用的是 Python 3,并且从 3.3 版开始,您不必遵循上述出色答案中给出的解决方案。
print build-in type 有一个选项 flush,默认情况下是 False。做:

print('opened', flush=True)

from http.server import HTTPServer, SimpleHTTPRequestHandler

server_address = ('', 8000)
httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)

print('Listening at https://127.0.0.1:8000/ . . .', flush=True)
httpd.serve_forever()

PS:

import logging
logging.info('Listening at https://127.0.0.1:8000/ . . .')

您好,请考虑使用日志记录而不是打印,您不想为打印语句的所有缺点而烦恼。打印是给初学者的,可能是为了交互模式。所有专业的服务器端编码员都依赖日志记录。

检查 In python, why use logging instead of print? 完整的日志记录优点列表。

这种现象有几种解决方法:

禁用输出缓冲

以写入模式重新打开 stdout 文件描述符,缓冲区大小为 0(无缓冲)。我建议将此行写为代码中的第一行,这样,除了 stdout 缓冲区外,所有代码都将保持不变:

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

运行 python 带无缓冲二进制标准输出和标准错误

强制 stdout 和 stderr 流的二进制层(作为它们的缓冲区属性可用)是无缓冲的。如果写入控制台,文本 I/O 层仍将进行行缓冲,如果重定向到非交互式文件,则将进行块缓冲。

所以 运行 你的脚本是这样的:

python -u <your_pyScript>

或者通过设置环境变量PYTHONUNBUFFERED

flush 关键字参数设置为 true

从 Python 3.3 开始,您可以强制正常的 print() 函数刷新而不需要使用 sys.stdout.flush() 只需将 "flush" 关键字参数设置为 true:

print("...", flush=True)

将一个模块中的默认值更改为 flush=True

您可以在模块的全局范围内使用 functools.partial 更改打印功能的默认值:

import functools
print = functools.partial(print, flush=True)

我们可以看到它按预期工作:

>>> print('foo')
foo