为什么我尝试访问内置类方法属性而不是相同的内置函数属性时出错

时间:2017-06-30 15:20:31

标签: python

我试图弄乱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有点新意,所以我猜这是一件相当简单的事情,但整个星期都令我感到烦恼。

1 个答案:

答案 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!'