Terminology: There is no pipe anywhere in this scenario. (I edited the question to fix that). Pipes are a different type of file (a buffer inside the kernel).
This is a redirect to a regular file.
C stdio, and Python, default to making stdout line-buffered when it's connected to a TTY, otherwise it's full-buffered. Line-buffered means the buffer is flushed after a newline. Full-buffered means it's only flushed to become visible to the OS (i.e. with a
write() system call) when it's full.
You will see output eventually, in chunks of maybe 4kiB at a time. (I don't know the default buffer size.) This is generally more efficient, and means fewer writes to your actual disk. But not great for interactive monitoring, because output is hidden inside the memory of the writing process until it's flushed.
On Stack Overflow, there's a Disable output buffering Python Q&A which lists many ways to get unbuffered (or line-buffered?) output to stdout in Python. The question itself summarizes the answers.
Options include running
python -u (Or I guess putting
#!/usr/bin/python -u at the top of your script), or using the
PYTHONUNBUFFERED environment variable for that program. Or explicit flushing after some/all
print functions, like @Davey's answer suggests.
Some other programs have similar options, e.g. GNU grep has
--line-buffered, and GNU
--unbuffered, for use-cases like this, or for example piping the output of your python program. e.g.
./slowly-output-stuff | grep --line-buffered 'foo.*bar'.