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
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?
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
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
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.