函数对象的 __code__
属性里存在着许多东西。
例如函数:
1 | def foo(): |
中,函数的元数由 foo.__code__.co_argcount
获得,函数的字节码由 foo.__code__.co_code
获得。这些 __code__
对象中的属性都是只读的,但是 __code__
对象本身却是可读可写的。
所以我们可以通过这个属性来恶作剧,再定义一个函数:
1 | def bar(): |
(关于 foo bar 之类的函数名到底有什么含义,可以看这里,其实就是类似于中文中的我们常说的张三,李四)
两个函数定义好了,就可以进行移植了:
1 | foo.__code__ = bar.__code___ |
这个时候运行
1 | print foo() |
会得到的是: i am bar