{"id":2836,"date":"2026-04-24T12:00:00","date_gmt":"2026-04-24T12:00:00","guid":{"rendered":"https:\/\/www.askpython.com\/?p=2836"},"modified":"2026-09-29T16:23:48","modified_gmt":"2026-09-29T16:23:48","slug":"python-print-to-file","status":"publish","type":"post","link":"https:\/\/www.askpython.com\/python\/built-in-methods\/python-print-to-file","title":{"rendered":"Python &#8211; Print to File"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Python&#8217;s print() function defaults to writing to the console, but it also accepts a file keyword argument that redirects output to any writable file object. This works with any object that has a .write() method &#8212; files, io.StringIO, and similar streams. The idiomatic approach pairs print() with a context-managed file handle using with open(\u2026) as f:, which handles closing automatically.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Redirecting print() to a file is useful for logging during development, saving script output to disk without modifying program logic, and writing data export pipelines where you want human-readable output. Four common approaches exist, ranging from the recommended print(file=f) pattern to sys.stdout redirection and the logging module.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">TLDR<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use <code>print('text', file=f)<\/code> with <code>with open(path, 'w') as f:<\/code> &#8212; the standard approach<\/li>\n\n\n\n<li>Pass <code>file=f<\/code> explicitly &#8212; avoid <code>sys.stdout<\/code> redirection for normal file output<\/li>\n\n\n\n<li>Use mode <code>'w'<\/code> to overwrite or <code>'a'<\/code> to append. <code>print()<\/code> adds newlines automatically, unlike <code>f.write()<\/code><\/li>\n\n\n\n<li>For production logging, use the <code>logging<\/code> module with <code>FileHandler<\/code> instead of <code>print()<\/code><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">The print(file=f) Approach<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>print()<\/code> function accepts a <code>file<\/code> keyword argument that accepts any file-like object. The recommended pattern uses a context manager:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nwith open(&quot;output.txt&quot;, &quot;w&quot;) as f:\n    print(&quot;First line&quot;, file=f)\n    print(&quot;Second line&quot;, file=f)\n    print(&quot;Third line&quot;, file=f)\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">After running this, <code>output.txt<\/code> contains three lines. The context manager closes the file automatically when the <code>with<\/code> block exits, even if an exception occurs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To append instead of overwriting, change the mode to <code>'a'<\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nwith open(&quot;output.txt&quot;, &quot;a&quot;) as f:\n    print(&quot;Appended line&quot;, file=f)\n\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">f.write() vs print(file=f)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>f.write()<\/code> method and <code>print(file=f)<\/code> behave differently:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# write() does NOT add a newline by default\nwith open(&quot;output.txt&quot;, &quot;w&quot;) as f:\n    f.write(&quot;Line 1&quot;)\n    f.write(&quot;Line 2&quot;)  # Appears right after Line 1 on the same line\n\n# print() automatically adds a newline (unless end=&quot;&quot;)\nwith open(&quot;output.txt&quot;, &quot;w&quot;) as f:\n    print(&quot;Line 1&quot;, file=f)\n    print(&quot;Line 2&quot;, file=f)  # Each on its own line\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Use <code>f.write()<\/code> when you need precise control over what gets written &#8212; no automatic newlines, no spaces. Use <code>print(file=f)<\/code> for convenient line-by-line output where the newline should be added automatically.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One common mistake is opening the file without a context manager:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# WRONG - file is never explicitly closed\nprint(&quot;Data&quot;, file=open(&quot;output.txt&quot;, &quot;w&quot;))\n\n# RIGHT - context manager ensures close\nwith open(&quot;output.txt&quot;, &quot;w&quot;) as f:\n    print(&quot;Data&quot;, file=f)\n\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Redirecting sys.stdout<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Python&#8217;s <code>sys.stdout<\/code> is a file-like object that <code>print()<\/code> writes to by default. You can replace it with a custom file object to capture all <code>print()<\/code> calls:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport sys\n\n# Save original stdout\noriginal_stdout = sys.stdout\n\n# Redirect all print() calls to a file\nwith open(&quot;output.txt&quot;, &quot;w&quot;) as f:\n    sys.stdout = f\n    print(&quot;This goes to the file&quot;)\n    print(&quot;So does this&quot;)\n\n# Restore stdout\nsys.stdout = original_stdout\n\nprint(&quot;This prints to the console&quot;)\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This approach works but has significant drawbacks: it affects the entire process, makes debugging harder because console output disappears, and must be carefully restored or the program crashes. Reserve <code>sys.stdout<\/code> redirection for situations where you genuinely need to intercept all output &#8212; not for normal file writing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using the logging Module<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>logging<\/code> module is the right choice for production-grade file output. It supports multiple severity levels, log rotation, and structured output. The simplest file configuration uses <code>basicConfig<\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport logging\n\nlogging.basicConfig(\n    filename=&quot;app.log&quot;,\n    level=logging.DEBUG,\n    format=&quot;%(levelname)s: %(message)s&quot;\n)\n\nlogging.debug(&quot;Debug info&quot;)\nlogging.info(&quot;Process started&quot;)\nlogging.warning(&quot;Low memory&quot;)\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">For more control, use <code>FileHandler<\/code> directly:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport logging\n\nlogger = logging.getLogger(__name__)\nlogger.setLevel(logging.DEBUG)\n\nfile_handler = logging.FileHandler(&quot;app.log&quot;)\nfile_handler.setLevel(logging.DEBUG)\n\nformatter = logging.Formatter(&quot;%(asctime)s - %(levelname)s - %(message)s&quot;)\nfile_handler.setFormatter(formatter)\n\nlogger.addHandler(file_handler)\nlogger.info(&quot;Application running&quot;)\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The <code>logging<\/code> module is superior to <code>print()<\/code> for any output that survives beyond development &#8212; it supports rotation, multiple handlers, and configurable severity thresholds.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common Pitfalls<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Forgetting to close the file.<\/strong> Opening a file without a context manager or explicit <code>.close()<\/code> can leave data unflushed. Always use <code>with open(...) as f:<\/code>.<\/li>\n\n\n\n<li><strong>Using <code>'w'<\/code> instead of <code>'a'<\/code>.<\/strong> Write mode (<code>'w'<\/code>) truncates the file before writing. Append mode (<code>'a'<\/code>) preserves existing content and adds to the end.<\/li>\n\n\n\n<li><strong>Mixing <code>write()<\/code> and <code>print(file=f)<\/code> on the same handle.<\/strong> Both work, but they have different buffering behavior. Pick one approach per file and stick with it.<\/li>\n\n\n\n<li><strong>Printing to a closed file.<\/strong> If the context manager block exits before all prints complete, the file closes and subsequent writes raise <code>ValueError: I\/O operation on closed file<\/code>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Q: Does print(file=f) automatically flush the data?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By default, <code>print()<\/code> flushes its output when a newline is written (the <code>end=\"\\n\"<\/code> default). To flush immediately without a newline, use <code>print(value, file=f, flush=True)<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Q: Can print() write to a file opened in binary mode?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>print()<\/code> writes text to files opened in text mode (the default). For binary output, use <code>f.write()<\/code> on a file opened with <code>\"wb\"<\/code> &#8212; <code>print()<\/code> raises a <code>TypeError<\/code> on binary file handles.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Q: How is print(file=f) different from sys.stdout redirection?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>print(file=f)<\/code> explicitly targets a single file object and leaves <code>sys.stdout<\/code> unchanged. <code>sys.stdout<\/code> redirection affects every <code>print()<\/code> call in the entire process and requires manual restoration.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Q: Can I print to stdout and a file at the same time?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Yes &#8212; write to stdout explicitly while also writing to the file, or use <code>tee<\/code>-style logic where each print goes to both destinations. The <code>logging<\/code> module handles this with multiple handlers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Q: Does the logging module overwrite or append to the log file?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By default, <code>FileHandler<\/code> opens the file in append mode. Pass <code>mode='w'<\/code> when creating the handler to overwrite instead: <code>FileHandler(\"app.log\", mode='w')<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Python&#8217;s print() function defaults to writing to the console, but it also accepts a file keyword argument that redirects output to any writable file object. This works with any object that has a .write() method &#8212; files, io.StringIO, and similar streams. The idiomatic approach pairs print() with a context-managed file handle using with open(\u2026) as [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":67613,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-2836","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-built-in-methods"],"_links":{"self":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/2836","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/comments?post=2836"}],"version-history":[{"count":0,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/2836\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media\/67613"}],"wp:attachment":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media?parent=2836"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/categories?post=2836"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/tags?post=2836"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}