# How Python Compiles Source Code to Bytecode for Its Interpreter

DevFeed: [How Python Compiles Source Code to Bytecode for Its Interpreter](<https://devfeed.tech/articles/introduction-to-the-python-interpreter-part-4-it-s-dynamic-29437.md>)

Original publisher: [Read original article](<http://akaptur.github.com/blog/2013/12/03/introduction-to-the-python-interpreter-4/>)

Published: 2013-12-03T19:25:00Z

Content type: article

Language: en

Sources: [Allison Kaptur](<https://devfeed.tech/sources/allison-kaptur.md>)

Topics: [Python](<https://devfeed.tech/topics/python.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [compiled language](<https://devfeed.tech/topics/compiled-language.md>), [Code](<https://devfeed.tech/topics/code.md>), [function](<https://devfeed.tech/topics/function.md>)

Tags: [bytecode](<https://devfeed.tech/tags/bytecode.md>), [compilation](<https://devfeed.tech/tags/compilation.md>), [compiled-language](<https://devfeed.tech/tags/compiled-language.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [python](<https://devfeed.tech/tags/python.md>)

## AI overview

This fourth article in a series on the Python interpreter explains how Python can be dynamic while still being compiled. It describes Python's compilation of source code into bytecode for a virtual machine and illustrates the process with a function and its disassembled bytecode.

## Source excerpt

[Edit: A significantly expanded version of this series appears as a chapter in The Architecture of Open Source Applications, volume 4, as A Python Interpreter Written in Python.] This is Part 4 in a series on the Python interpreter. Read Part 1, Part 2, and Part 3. If you're enjoying this series, consider applying to Hacker School, where I work as a facilitator. One of the things I was confused about when I started digging into python internals was how python could be "dynamic" if it was also "compiled." Often, in casual coversation, those two words are used as antonyms - there are "dynamic languages,"1 like Python, Ruby, and Javascript, and "compiled languages," like C, Java, and Haskell. Most of the time, when people talk about a "compiled" language, they mean one that compiles down to native x86/ARM/etc instructions2 - instructions for an actual machine made of metal. An "interpreted" language either doesn't have any compilation at all3, or compiles to an intermediate representation, like bytecode. Bytecode is instructions for a virtual machine, not a piece of hardware. Python falls into this latter category: the Python compiler's job is to generate bytecode for the Python interpreter.4 The Python interpreter's job is to make sense of the bytecode via the virtual machine, which turns out to be a lot of work. We'll dig in to the virtual machine in Part 5. So far our discussion of compiling versus interpretation has been abstract. These ideas become more clear with an example. 1 2 3 4 5 6 7 8 9 10 >>> def modulus(x, y): ... return x % y ... >>> [ord(b) for b in modulus.func_code.co_code] [124, 0, 0, 124, 1, 0, 22, 83] >>> dis.dis(modulus.func_code) 2 0 LOAD_FAST 0 (x) 3 LOAD_FAST 1 (y) 6 BINARY_MODULO 7 RETURN_VALUE Here's a function, its bytecode, and its bytecode run through the disassembler. By the time we get the prompt back after the function definition, the modulus function has been compiled and a code object generated. That code object will never be modified