如何将一个类中的现有实例方法绑定到另一个类?

时间:2011-07-08 16:20:41

标签: python

我正在尝试在类上进行有限形式的动态混合,从第三方库类中获取方法并将它们绑定到我的类。但我尝试过的任何东西都没有正常工作。我在别处看到的所有示例都将一个未绑定的函数绑定到一个类,但在我的情况下,我需要将已绑定的方法绑定到另一个类。

我一直在使用的一些示例代码,包括我的失败尝试:

import types
import traceback

class Class1(object):
    output = 'class1'
    def method(self):
        print self.output

class Class2(object):
    output = 'class2'

try:
    Class2.method = types.MethodType( Class1.method, None, Class2 )
    class2 = Class2()
    class2.method()
except:
    traceback.print_exc() # TypeError: unbound method method() must be called with Class1 instance as first argument (got Class2 instance instead)

try:
    class1 = Class1()
    class2 = Class2()
    class2.method = types.MethodType( class1.method, class2, Class2 )
    class2.method()
except:
    traceback.print_exc() # TypeError: method() takes exactly 1 argument (2 given)

class1 = Class1()
class2 = Class2()
class2.method = class1.method.__get__( class2, Class2 )
class2.method() # outputs 'class1' not 'class2'

这可能吗?难道我做错了什么?还有其他一种我没见过的技术吗?

3 个答案:

答案 0 :(得分:7)

通过修改YourClass.__bases__

动态地将其添加为父类
>>> class Base: pass
>>> class Foo(Base): pass
>>> class Bar(Base): attr = True
>>> Foo.__bases__ = (Bar,) + Foo.__bases__
>>> Foo.attr
True

或者,获取绑定的方法对象并提取原始函数,然后将其作为原始类的属性附加:

YourClass.method = OtherClass.bound_method.im_func

编辑:您修改__bases__而不是__mro__。糟糕。

答案 1 :(得分:1)

您的代码中的一些修改,希望它会工作。

import types

class Class1(object):
  output = 'class1'
  def method(self):
    print self.output

class Class2(object):
  output = 'class2'

# you have to use im_func - bound or even unbound methods will fail
class1Method = Class1().method.im_func 

Class2.method = types.MethodType(class1Method, Class2(), Class2)
Class2().method() # it will print 'class2'

答案 2 :(得分:0)

您是否考虑过创建一个元类,允许您通过覆盖mro()来动态分配父类,以便以后执行时调用它?


回应您最近的评论:在单元测试开始执行后,您可以使用工厂函数生成所需的类。这可能适用于使用元类的想法。