print()是Python 3的内置函数,必须加括号调用;支持重定向到文件或StringIO、自定义分隔符与结尾符、手动刷新缓冲区,但无返回值,高频日志应改用logging。

Python 的 print() 不只是“输出一行文字”那么简单——它默认写到标准输出(sys.stdout),但可以重定向到文件、字符串缓冲区,甚至自定义对象;它的行为在 Python 2 和 3 之间有本质区别,而很多人卡在第一行就出错,比如加了括号却用 Python 2 运行,或漏掉 flush=True 导致日志不实时。
print() 是函数,不是语句:Python 3 的基本调用方式
Python 3 中 print 是内置函数,必须加括号。不加括号会直接报错:SyntaxError: Missing parentheses in call to 'print'。
基础用法支持多个参数,默认用空格分隔,末尾自动换行:
print("Hello", "World", 42) # 输出:Hello World 42
print("No", "newline", end="") # 输出后不换行,接续下一次 print
print("here") # 结果是:No newlinehere常见误区:
立即学习“Python免费学习笔记(深入)”;
- 误以为
sep或end只能是字符串——其实必须是str类型,传入None或数字会报TypeError - 在循环中频繁打印调试信息时没设
flush=True,导致输出卡在缓冲区,看不到实时日志 - 把
print当作表达式使用(如x = print("hi")),结果x是None,因为print()没有返回值
把 print 输出重定向到文件,而不是屏幕
用 file 参数就能把内容写进文件,无需手动打开/关闭(但要注意:它不会自动追加,而是覆盖):
with open("log.txt", "w") as f:
print("Start processing...", file=f)
print("Step 1 done", file=f)如果想追加内容,打开文件时用 "a" 模式即可;若要避免每次手动传 file=f,可临时替换 sys.stdout,但需谨慎——会影响所有未指定 file 的 print() 调用。
关键细节:
-
file参数接受任何实现了write()和flush()方法的对象,比如io.StringIO(用于捕获输出做测试) - 写入文件时,
print()不处理编码,实际编码由文件对象决定(推荐显式指定encoding="utf-8"在open()中) - 别用
print(..., file=open("x.txt", "w"))这种写法——文件没关闭,资源泄漏,且多次调用会反复覆盖
捕获 print 输出:用于测试、日志预处理或调试
想验证某段代码里 print() 是否输出了预期内容?用 io.StringIO 替换 sys.stdout 最直接:
import io import sysold_stdout = sys.stdout sys.stdout = captured = io.StringIO()
print("Test output") print(123)
sys.stdout = old_stdout output = captured.getvalue() # → "Test output\n123\n"
更安全的做法是用上下文管理器封装,避免忘记还原 sys.stdout;另外注意:StringIO 只处理文本,不能用于二进制重定向。
注意点:
- 多线程环境下修改
sys.stdout是全局的,会影响其他线程——此时应始终用file=参数局部重定向 - 某些 IDE(如 PyCharm)或 Jupyter 会劫持
sys.stdout,导致重定向行为异常,优先用file=参数 -
captured.getvalue()返回的是带换行符的完整字符串,记得用.strip()去除首尾空白再断言
性能与兼容性:什么时候不该用 print()
高频日志场景(比如每毫秒打一条)下,print() 的缓冲、格式化、I/O 开销明显高于直接调用 sys.stdout.write() 或专业日志库(logging)。而且 print() 无法设置日志级别、格式模板或异步写入。
跨版本兼容是个隐形坑:Python 2 的 print 是语句,写成 print "hello";混用会导致语法错误。若必须兼容,可用 from __future__ import print_function 强制 Python 2 支持函数式写法,但仅限模块开头,且不解决底层差异(如 Unicode 处理)。
真实建议:
- 脚本级简单输出、调试、教学示例,放心用
print() - 服务端、长时间运行程序、需要结构化日志的场景,立刻换
logging,别硬撑 - 生成大量中间文本(如模板渲染)时,用
io.StringIO+write()比拼接print(..., file=buf)更快
最常被忽略的一点:print 的 flush 参数默认为 False,但在交互式脚本、子进程通信、容器日志采集时,缓冲会导致“明明执行了却看不到输出”。加一句 flush=True 成本极低,却是排查卡顿问题的第一检查项。











