Hi Pythonistas!,
In the previous posts, we looked at how Python compiles conditionals and loops into bytecode. Now, let’s dive into function calls and see how Python manages function execution with bytecode.
Disassembling a Function with Arguments
Let’s start with a simple example of a function that takes arguments and returns a value
import dis
def multiply(a, b):
return a * b
dis.dis(multiply)
Output
2 0 LOAD_FAST 0 (a)
2 LOAD_FAST 1 (b)
4 BINARY_MULTIPLY
6 RETURN_VALUE
Here’s what the bytecode instructions mean:
LOAD_FAST 0 (a): Load the local variable a onto the stack.
LOAD_FAST 1 (b): Load the local variable b onto the stack.
BINARY_MULTIPLY: Multiply a and b.
RETURN_VALUE: Return the result of a * b.
Disassembling a Function with a Default Argument
Next, let’s examine a function with default arguments:
code
def power(x, exp=2):
return x ** exp
dis.dis(power)
Output
2 0 LOAD_FAST 0 (x)
2 LOAD_FAST 1 (exp)
4 BINARY_POWER
6 RETURN_VALUE
In this case, Python disassembles the function in the same way as before, but it internally handles the default argument (exp=2) when the function is called with fewer arguments than required.
In the upcoming post we will learn more about nested functions