Assembling Bytecode - PyCode New
以下代码以字符串形式生成字节码输出。我想替换一些字节码行,重新组装并执行它。我需要像字节数字那样的东西吗?或者我可以用新的pycode来做这个吗?
http://docs.python.org/2/c-api/code.html_pycode_new
http://pypi.python.org/pypi/bytecodeassembler
输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ********** code ********** type: <type 'str'> def test(a,b): return a*b test(2,3) ********** compiles into the bytecode ********** type: <type 'code'> 1 0 LOAD_CONST 0 (<code object test at 0x101d1ca30, file"<string>", line 1>) 3 MAKE_FUNCTION 0 6 STORE_NAME 0 (test) 3 9 LOAD_NAME 0 (test) 12 LOAD_CONST 1 (2) 15 LOAD_CONST 2 (3) 18 CALL_FUNCTION 2 21 POP_TOP 22 LOAD_CONST 3 (None) 25 RETURN_VALUE 3 ********** bytecode ********** 'd\x00\x00\x84\x00\x00Z\x00\x00e\x00\x00d\x01\x00d\x02\x00\x83\x02\x00\x01d\x03\x00S' |
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import dis import sys import inspect import new class writer: def __init__(self): self.s ="" def write(self,text): #print ': ',text self.s += text #save stdout origstdout = sys.stdout w = writer() sys.stdout = w s ="def test(a,b): \treturn a*b test(2,3)" c = compile(s,'<string>','exec') # dis calls stdout, so output is in w bytecode = dis.dis(c) sys.stdout = origstdout def h(x): print '*'*10 + '\t' + x + '\t' + '*'*10 + ' '*1 h('code') print 'type: '+str(type(s)) print s + ' ' h('compiles into the bytecode') print 'type: '+str(type(c)) print w.s h('bytecode') print repr(c.co_code) |
BytePlay是一个很好的Python代码对象包装器。它有自己的代码类。代码对象是特定于cpython的,并且更复杂。开始的时候最好先玩byteplay。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | from byteplay import * def foo(): x = 10 print 'inside ',x return 42 c = Code.from_code(foo.func_code) print c.code ret = foo() print 'outside: ',ret c.code[10] = (LOAD_CONST,1000) foo.func_code = c.to_code() print '*'*20 print c.code ret = foo() print 'outside: ',ret |
生产
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 4 1 LOAD_CONST 10 2 STORE_FAST x 5 4 LOAD_CONST 'inside ' 5 PRINT_ITEM 6 LOAD_FAST x 7 PRINT_ITEM 8 PRINT_NEWLINE 6 10 LOAD_CONST 42 11 RETURN_VALUE inside 10 outside: 42 ******************** 4 1 LOAD_CONST 10 2 STORE_FAST x 5 4 LOAD_CONST 'inside ' 5 PRINT_ITEM 6 LOAD_FAST x 7 PRINT_ITEM 8 PRINT_NEWLINE 6 10 LOAD_CONST 1000 11 RETURN_VALUE inside 10 outside: 1000 |