添加基类在python现有对象(Adding base class to existing obje

2019-06-25 11:56发布

我有不同种类的多个对象(不同的函数名,不同的签名),我猴子修补它们必须从不同的功能访问他们的常用方法。 简单地说,有可能发生,我想修补和根据不同的对象类型调用不同的补丁对象调度员。 修补器将方法添加到对象:

def patcher_of_some_type(object):

    def target(self, value):
        # do something and call self methods

    object.target = types.MethodType(target, object)

    # many more of these

由于程序变得更复杂,使得周围的物体(或对象类)的包装似乎是更好的主意。 一些patchers共享公共代码或者是相互关联的。 但我不控制对象创建,也不是类创建。 我只得到了对象。 即使我能做到这一点,我只是想换行(或补丁)的特定对象,不是全部。

一种解决方案可能是一个基类添加到现有的对象,但我不知道如何维护和安全的,这是。 有另一种解决方案?

Answer 1:

动态修改一个对象的类型是相当安全的,只要额外的基类是兼容的(你会得到一个异常,如果它不是)。 加入碱类的最简单的方法是使用3个参数的type构造函数:

cls = object.__class__
object.__class__ = cls.__class__(cls.__name__ + "WithExtraBase", (cls, ExtraBase), {})


Answer 2:

根据评论的另一个答案,这是另一种方式来修补的基类:

class Patched(instance.__class__, ExtraBase):
    pass

instance.__class__ = Patched


Answer 3:

一类添加到其他类基地,你可以这样做:

def pacher_of_some_type(object):

    #this class holds all the stuff you want to add to the object
    class Patch():
        def target(self, value):
            #do something

    #add it to the class' base classes
    object.__class__.__bases__ += (Patch, )

但是,这会影响这个类的所有对象和你实际改变类本身,这似乎并没有你想要的......如果你只是想修补的情况下,你可以继承原班和改变实例类动态:

class PatchedClass(object.__class__):
    def target(self, value):
        #do whatever

object.__class__ = PatchedClass

在安全性和可管理性方面,我会说,动态添加,因为你不太可能意外覆盖原始类的一些内部功能,因为新的基类增加是一个基类是为维护动态地增加了一些功能,更安全到元组的结束,这意味着它是最后使用的名称解析。 如果你真的想覆盖的方法,将它们添加到基类的元组的开始(当然这并不适用于子类的方法)。 不要问我,如果动态地改变类的实例是安全可言,但在一个简单的例子,似乎没有什么是一个问题:

class A():
    def p(self): print 1

class B():
    def p(self): print 2

a = A()
a.p()    #prints 1
a.__class__ = B
a.p()    #prints 2


文章来源: Adding base class to existing object in python