pythonw.exe
python.exe
Python scripting
command line
Windows Python

pythonw.exe or python.exe?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

python.exe runs Python scripts with a console window attached. pythonw.exe runs them without one. Use python.exe for command-line tools, scripts, and debugging. Use pythonw.exe for GUI applications and background processes where a console window would be unwanted. The .pyw file extension is the file-association equivalent of pythonw.exe, so double-clicking a .pyw file launches it without a console.

How They Differ Internally

Both executables run the same Python interpreter and execute the same bytecode. The only difference is in how Windows handles the process at the OS level.

python.exe is linked as a console application (the SUBSYSTEM flag in the PE header is set to CONSOLE). When Windows launches a console application, it either attaches it to the existing console or creates a new console window. This is why running a Python script from Explorer by double-clicking a .py file briefly flashes a black window.

pythonw.exe is linked as a Windows GUI application (SUBSYSTEM is set to WINDOWS). Windows does not create or attach a console window for GUI subsystem processes. The standard streams (sys.stdin, sys.stdout, sys.stderr) are set to None.

text
python.exe   -> SUBSYSTEM:CONSOLE  -> console window attached
pythonw.exe  -> SUBSYSTEM:WINDOWS  -> no console window

When to Use Each

ScenarioUseWhy
CLI tools and scriptspython.exeYou need to see output and interact with stdin
Debugging any scriptpython.exeError messages and stack traces appear in the console
GUI apps (tkinter, PyQt, wxPython)pythonw.exeA console window behind the GUI is distracting
Background services / tray appspythonw.exeNo visible console window needed
Scheduled tasks (Task Scheduler)pythonw.exeAvoids a console window popping up on schedule
Jupyter notebookspython.exeThe kernel needs console I/O

The .py vs .pyw File Extension

Windows file associations connect .py files to python.exe and .pyw files to pythonw.exe. This means the file extension controls which executable runs when you double-click a script in Explorer.

text
script.py   -> double-click -> runs with python.exe  (console appears)
script.pyw  -> double-click -> runs with pythonw.exe (no console)

From the command line, you can always choose explicitly:

cmd
python.exe script.py
pythonw.exe script.py

The file extension does not matter when you invoke the interpreter directly. It only matters for double-click behavior.

The stdout Problem with pythonw.exe

Because pythonw.exe does not attach a console, sys.stdout and sys.stderr are None. Any print() call or unhandled exception that tries to write to these streams will raise an AttributeError or silently disappear, depending on the Python version.

This is the most common source of confusion. A script works perfectly with python.exe but silently fails with pythonw.exe.

Solution: redirect output to a log file

python
1import sys
2import logging
3
4# Configure logging to a file
5logging.basicConfig(
6    filename="app.log",
7    level=logging.INFO,
8    format="%(asctime)s %(levelname)s %(message)s",
9)
10
11# Redirect stdout/stderr so print() doesn't crash
12if sys.stdout is None:
13    sys.stdout = open("app_stdout.log", "w")
14if sys.stderr is None:
15    sys.stderr = open("app_stderr.log", "w")
16
17logging.info("Application started")
18print("This goes to app_stdout.log when run with pythonw.exe")

Solution: use a NullWriter for silent operation

If you do not care about output at all:

python
1import sys
2import os
3
4class NullWriter:
5    def write(self, s):
6        pass
7    def flush(self):
8        pass
9
10if sys.stdout is None:
11    sys.stdout = NullWriter()
12if sys.stderr is None:
13    sys.stderr = NullWriter()

A Practical GUI Example

Here is a minimal tkinter application. Running it with pythonw.exe gives a clean GUI window without a console lurking behind it:

python
1# save as app.pyw
2import tkinter as tk
3
4def on_click():
5    label.config(text="Button clicked!")
6
7root = tk.Tk()
8root.title("Example App")
9root.geometry("300x150")
10
11label = tk.Label(root, text="Hello from pythonw.exe", font=("Arial", 14))
12label.pack(pady=20)
13
14button = tk.Button(root, text="Click me", command=on_click)
15button.pack()
16
17root.mainloop()

Save this as app.pyw and double-click it. The GUI appears with no console window.

The Python Launcher (py.exe)

On Windows, the Python Launcher (py.exe) was introduced to handle multiple Python versions. It reads shebang lines and version specifiers:

cmd
py script.py         # runs with default python.exe
pyw script.py        # runs with default pythonw.exe
py -3.11 script.py   # runs with Python 3.11's python.exe

The launcher respects the .py / .pyw extension convention and can be configured via py.ini for custom defaults.

Task Scheduler and Services

When setting up a scheduled task in Windows Task Scheduler, use pythonw.exe as the program to avoid a console window popping up every time the task fires:

text
Program/script:    C:\Python312\pythonw.exe
Add arguments:     C:\scripts\backup.py
Start in:          C:\scripts

For Windows services, consider using a dedicated service wrapper like pywin32's win32serviceutil or NSSM, which handle process lifecycle management beyond what pythonw.exe alone provides.

Comparison Table

Featurepython.exepythonw.exe
Console windowYes (created or attached)No
sys.stdoutConnected to consoleNone
sys.stderrConnected to consoleNone
sys.stdinConnected to consoleNone
PE subsystemCONSOLEWINDOWS
File association.py.pyw
Use caseCLI, debugging, scriptsGUI apps, background tasks
Error visibilityErrors print to consoleErrors are silent unless logged

Common Pitfalls

Using pythonw.exe for debugging. When sys.stderr is None, exceptions vanish silently. You will not see any error output. Always develop and debug with python.exe, then switch to pythonw.exe for deployment.

Calling print() without guarding stdout. print() writes to sys.stdout, which is None under pythonw.exe. Either redirect to a file, use the logging module, or wrap sys.stdout with a null writer.

Assuming .pyw changes the script behavior. The extension only affects which executable Windows uses when double-clicking the file. The Python code inside runs identically. If you invoke python.exe script.pyw, it will still open a console.

Running a Flask/Django dev server with pythonw.exe. Web framework dev servers produce output on stdout and expect console interaction for shutdown. Use python.exe for development servers.

Forgetting to flush log files. When redirecting output to files under pythonw.exe, buffering may delay writes. Use flush=True in print() calls or configure logging handlers with flush behavior.

Summary

  • python.exe creates a console window and connects standard I/O streams. Use it for command-line tools, scripts, and all development/debugging work.
  • pythonw.exe suppresses the console window and sets sys.stdout/sys.stderr to None. Use it for GUI applications, background processes, and scheduled tasks.
  • The .pyw file extension tells Windows to use pythonw.exe when double-clicking the script.
  • Always add logging or output redirection to scripts intended for pythonw.exe, because errors will be invisible without it.
  • The Python Launcher (py.exe / pyw.exe) provides version selection and respects the same console/no-console distinction.
  • Develop with python.exe. Deploy with pythonw.exe when a console-free experience is needed.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.