如何让Python脚本像pytest -s一样实时输出标准输出?
Great question! Let’s start by breaking down why this difference exists, then walk through simple fixes to replicate pytest’s real-time output behavior in your script.
First, the root cause: Python buffers standard output (stdout) by default. When you run python3 script.py, the buffering rules change based on where stdout is sent:
- If connected to an interactive terminal (your regular command line), it uses line buffering (flushes output when it hits a newline).
- If redirected to a file/pipe or run in a non-interactive environment, it switches to full buffering (only flushes when the buffer is full or the program exits).
Pytest’s -s flag disables output capturing and forces unbuffered stdout, which is why you see updates in real time. Here are 4 straightforward ways to get the same behavior for your script:
1. Use the -u Command-Line Flag
The easiest fix—no code changes required. Run your script with the -u (unbuffered) flag, which forces stdout and stderr to skip buffering entirely:
python3 -u script.py
This matches exactly how pytest handles output when using -s.
2. Add flush=True to Specific print() Calls
If you only need certain lines to show up in real time, modify your print statements to explicitly flush the buffer:
print("API call completed: 200 OK", flush=True)
This is perfect for granular control—you don’t have to change how you run the script, just target the outputs that matter most.
3. Set the PYTHONUNBUFFERED Environment Variable
Enable unbuffered output by setting an environment variable before running your script:
PYTHONUNBUFFERED=1 python3 script.py
Or, if you want this to apply to all Python runs in your session, export the variable first:
export PYTHONUNBUFFERED=1 python3 script.py
This is handy if you don’t want to remember to add -u every time you run the script.
4. Force Unbuffered Stdout in the Script Itself
If you want the script to enforce real-time output no matter how it’s run, add this at the very top of your code:
import sys # Set stdout to line-buffered (flushes on newline) sys.stdout = open(sys.stdout.fileno(), 'w', buffering=1)
Line buffering (buffering=1) works for most cases since print statements usually end with a newline. If you need output without newlines to show up immediately, use binary mode with buffering=0 (note: this requires writing bytes instead of strings).
内容的提问来源于stack exchange,提问作者Open Food Broker




