Investigation
I have this program
def gen_baz():
return 2
def gen_bar(a, b, c=1):
return a, b, c
# ---------- #
# Save the code objects
c1 = gen_bar.__code__
c2 = gen_baz.__code__
dis.dis(gen_bar) # [Disassambly 1]
print(inspect.getsource(gen_bar)) # [Inspect 1]
bar = gen_bar(1, 2) # bar: (1, 2, 1)
baz = gen_baz() # baz: 2
print(f"before: bar={bar}, baz={baz}")
# --------- #
gen_bar.__code__, gen_baz.__code__ = c2, c1 # swap code objects between 2 functions
dis.dis(gen_baz) # [Disassambly 2]
print(inspect.getsource(gen_baz)) # [Inspect 1]
bar = gen_bar() # bar: 2
baz = gen_baz(1, 2) # baz: [Error 1]
print(f"after: bar={bar}, baz={baz}")
Here are the outputs with Disassembly and Inspect
[Disassembly 1 & 2]
17 0 LOAD_FAST 0 (a)
2 LOAD_FAST 1 (b)
4 LOAD_FAST 2 (c)
6 BUILD_TUPLE 3
8 RETURN_VALUE
[Inspect 1 & 2]
def gen_bar(a, b, c=1):
return a, b, c
[Error 1]
Traceback (most recent call last):
File "C:\Users\something\test.py", line 32, in <module>
baz = gen_baz(1, 2)
TypeError: gen_baz() missing 1 required positional argument: 'c'
Question
- Why after I swapped the code objects between baz and bar, the program crashed? Even though they have identical byte code and inspect result
- Where is the default parameter in python stored? Does it come along with the function object but not the code object? If so, then how does Inspect module gives me
c=1on the second inspection?
Thanks a lot!
>Solution :
Check the docs:
__code__: code object containing compiled function bytecode__defaults__: tuple of any default values for positional or keyword parameters__kwdefaults__: mapping of any default values for keyword-only parameters