sdsmith sdsmith - 3 months ago 13
Python Question

What is function.__code__ behavior across multiple program executions?

I am working on a caching system. The idea is it can detect if the function that created the cache object has changed since its initial creation, therefore invalidating the cache file.

I stumbled across python's

attribute, that is the compiled function's byte code representation. I can't find much additional documentation on the matter, and was wondering what its behaviour is across different executions of a single program.

I assume that because python is an interpreted language, the byte code will be platform independent. I also assume that its byte code generation is deterministic for a given input. Am I right in thinking so?

Answer

The function.__code__ attribute returns an object encapsulating the virtual machine bytecode.

def f(): return 3
print(dir(f.__code__))
print(f.__code__.co_code)  # raw compiled bytecode

Another way to access the information is to compile explicitly a file. Here is a file test.py:

def f(): return 3

Then, you can type in the python prompt:

>>> c = compile('test.py', 'test.py', 'exec')
>>> print(c.co_code)  # here is some bytecode

A simple and funny way to access the bytecode, in a very legible way, is to run it in a terminal (here, dis is the disassembler):

python -m dis test.py

Which outputs:

1         0 LOAD_CONST               0 (<code object f at 0x7fe8a5902300, file "p.py", line 1>)
          3 LOAD_CONST               1 ('f')
          6 MAKE_FUNCTION            0
          9 STORE_NAME               0 (f)
         12 LOAD_CONST               2 (None)
         15 RETURN_VALUE

This bytecode is not platform dependent. The VM is.


About eventual changes in bytecode, I have taken this file, and disassembled it twice:

python3 -m dis file.py > test1
python3 -m dis file.py > test2

Then a simple diff shows that:

89c89
<  26         204 LOAD_CONST              13 (<code object search_concept at 0x7f40de337300, file "powergrasp/compression.py", line 26>)
---
>  26         204 LOAD_CONST              13 (<code object search_concept at 0x7fd8de5ab300, file "powergrasp/compression.py", line 26>)
104c104
<             240 LOAD_CONST              19 (<code object compress_lp_graph at 0x7f40de340780, file "powergrasp/compression.py", line 55>)
---
>             240 LOAD_CONST              19 (<code object compress_lp_graph at 0x7fd8de5b4780, file "powergrasp/compression.py", line 55>)

The changes are mainly regarding imports, where the address of the loaded modules are not the same across the compilation.

Comments