Fundamentals 9 min read

Understanding Python .py Script Execution and Bytecode Generation

This article explains how Python executes .py scripts by compiling source code to bytecode, the role of the virtual machine, when and how .pyc and .pyo files are generated, and practical commands and options for optimizing and managing Python bytecode.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Understanding Python .py Script Execution and Bytecode Generation

Python enthusiasts should know that a .py script is not compiled into a binary executable; instead the Python interpreter reads the source, compiles it to bytecode, and then the virtual machine executes that bytecode.

The interpreter has three notable characteristics: the source code stays far from the hardware, bytecode is generated at runtime and run by the VM, and each execution involves a loading and linking step, which can make it slower than compiled languages.

The VM executes a script by loading and linking the module, translating the source into a PyCodeObject (the bytecode) stored in memory, reading and executing the instructions, and finally deciding whether to write the bytecode back to disk as a .pyc or .pyo file.

Whether a .pyc/.pyo file is created depends on how the script is run. Running a directory (e.g., python path/to/projectDir) creates a __pycache__ folder with bytecode files for all modules; running a single file creates a bytecode file only for that module.

When a module is imported, Python checks the modification time of the existing bytecode file; if it matches the source, the bytecode is used directly, otherwise the source is re‑compiled and the bytecode file is updated.

.pyc files contain compiled bytecode, which loads faster and can obscure source code; .pyo files are further optimized (smaller) and are useful for embedded systems. Both are placed in __pycache__.

Common optimization flags are -O (produces .pyo), -OO (removes docstrings), and -m (run a module as a script).

To generate a .pyc file from the command line you can use:

python -m py_compile /path/to/your_script.py  # generate .pyc (or batch with a pattern)

Or from Python code:

import py_compile
py_compile.compile(r'/path/to/your_script.py')
# The function signature is py_compile.compile(file[, cfile[, dfile[, doraise]]])

To generate a .pyo file you can run: python -O -m py_compile /path/to/your_script.py Both commands create a __pycache__ directory in the script’s location. .pyd files are Python dynamic‑link libraries and are outside the scope of this discussion.

Other ways to produce bytecode include using the compileall module or IDEs that automatically compile scripts.

Understanding Python’s execution model and bytecode generation helps when designing caching systems, reducing unnecessary runtime overhead, and keeping code up‑to‑date.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

performanceCompilationpy_compile
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.