遇到一个需求,需要为单例对象新增方法,这个方法来自于单例的子类或是一个独立的函数。
在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.方法名
来调用他。同时也会将实例作为第一个参数。