我试图弄乱python字节码(3.6中的字码),只是为了获得一些探索性的乐趣。我正在使用byteplay3来更改__code__
属性,在使用函数时,一切都很好,花花公子。
from byteplay3 import *
def foo():
print('bar')
def monty():
print('python')
c = Code.from_code(foo.__code__)
d = Code.from_code(monty.__code__)
foo.__code__ = d.to_code()
输出:
>>>foo()
python
当我用类方法尝试相同的事情时,
class King(object):
def __init__(self):
print('King of the Britons')
def bro(self):
print('bruh')
Arthur = King()
f = Code.from_code(Arthur.bro.__code__)
一切正常,直到我尝试改变类方法的__code__
属性。
Arthur.bro.__code__ = d.to_code()
当我确信有一个时,我得到“'方法没有属性__code__
”错误。我可以使用dis模块print(f.code)
或反汇编Arthur.bro.__code__
并获得
24 1 LOAD_GLOBAL print
2 LOAD_CONST 'bruh'
3 CALL_FUNCTION 1
4 POP_TOP
5 LOAD_CONST None
6 RETURN_VALUE
所以,我错过了什么?我对python有点新意,所以我猜这是一件相当简单的事情,但整个星期都令我感到烦恼。
答案 0 :(得分:0)
这里的关键似乎是类和对象(或类的实例)之间的区别。为每个类组装字节码,而不是每个类的实例。要在示例中获得所需的行为,您需要执行以下操作。
# two example classes
class Cat():
def says(self):
print('meow!')
class Dog():
def says(self):
print('woof!')
# setup as objects
c, d = Cat(), Dog()
# change the class bytecode
Dog.says.__code__ = Cat.says.__code__
# and we get a very confused dog...
d.says() # 'meow!'