我正在开发一个缓存系统。我们的想法是它可以检测创建缓存对象的函数自初始创建以来是否已更改,从而使缓存文件无效。
我偶然发现了python的function.__code__
属性,即编译函数的字节码表示。我无法找到关于此事的更多文档,并且想知道在单个程序的不同执行中它的行为是什么。
我认为因为python是一种解释型语言,所以字节代码将与平台无关。我还假设其字节码生成对于给定输入是确定性的。我这么想是对的吗?
答案 0 :(得分:2)
函数.__ code__属性返回一个封装虚拟机字节码的对象。
def f(): return 3
print(dir(f.__code__))
print(f.__code__.co_code) # raw compiled bytecode
访问信息的另一种方法是显式编译文件。
这是一个文件test.py
:
def f(): return 3
然后,您可以输入python提示符:
>>> c = compile('test.py', 'test.py', 'exec')
>>> print(c.co_code) # here is some bytecode
以一种非常清晰的方式访问字节码的简单而有趣的方法是在终端中运行它(这里,dis
是反汇编程序):
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
此字节码不依赖于平台。 VM是。
关于字节码的最终更改,我已经使用了this file,并将其反汇编了两次:
python3 -m dis file.py > test1
python3 -m dis file.py > test2
然后一个简单的差异表明:
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>)
更改主要涉及导入,其中加载模块的地址在编译过程中不同。