动态的为 对象绑定方法
遇到一个需求,需要为单例对象新增方法,这个方法来自于单例的子类或是一个独立的函数。
在Python
中实例的方法由创建它的类来提供,也就是方法是属于类的,在对象空间中并不存在。但是通过实例来修改其类的方法或属性不是一个好的行为。这会让程序看起来非常糟糕。
我们希望将方法绑定到对象的空间中。虽然这看起来也不符合变成习惯,但是总比修改类来的优雅。
Python 在 types.MethodType
中提供了这样的方法。
import types
class Person(object):
""" 定义一个属性 name 和一个方法 func """
def __init__(self, name):
self.name = name
# 实例化时就会赋予的方法
def func(self):
print("Old method!\n\rMy name is %s ." % self.name)
p = Person('Monkey')
# 为 Person 的实例动态添加这个方法 必须穿入 self 对象 代表实例本身
def function(self, *args, **kwargs):
print("New method!\n\rMy name is %s ." % self.name)
# types.MethodType 方法 会将 第一个参数作为绑定方法,绑定到 第二个参数中 同时将实例本身作为第一个参数传入。
p.function = types.MethodType(function, p)
p.func()
p.function()
print(id(function)) # 140414285538712
print(id(p.function)) # 140414256994760
print(function) # <function function at 0x7f82b05c5ea0>
print(p.function) # <bound method function of <__main__.Person object at 0x7f82b07e3400>>
可以看到,确实如我们预期的样子,它成功的将function
绑定到了实例空间中。并且我们能像使用实例的方法一样通过 obj.方法名
来调用他。同时也会将实例作为第一个参数。