Loading

动态的为 对象绑定方法

遇到一个需求,需要为单例对象新增方法,这个方法来自于单例的子类或是一个独立的函数。

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.方法名 来调用他。同时也会将实例作为第一个参数。

posted @ 2020-06-19 13:59  StKali  阅读(279)  评论(0编辑  收藏  举报