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

Python 如何将一个类中的现有实例方法绑定到另一个类?,python,Python,我试图对一个类进行有限形式的动态混合,从第三方库类获取方法并将它们绑定到我的类。但我试过的方法都不正确。我在别处看到的所有示例都将未绑定的函数绑定到一个类,但在我的例子中,我需要将一个已绑定的方法绑定到另一个类 我一直在使用的一些示例代码,失败的尝试包括: import types import traceback class Class1(object): output = 'class1' def method(self): print self.outpu

我试图对一个类进行有限形式的动态混合,从第三方库类获取方法并将它们绑定到我的类。但我试过的方法都不正确。我在别处看到的所有示例都将未绑定的函数绑定到一个类,但在我的例子中,我需要将一个已绑定的方法绑定到另一个类

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

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'

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

通过修改
YourClass动态地将其添加为父类

>>> 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

编辑:您可以修改
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
而不是
\uuuuuuuuuuuuuuuu。哦。

对代码进行一些修改,希望它能起作用

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'

您是否考虑过创建一个元类,该元类允许您通过重写
mro()
来动态分配父类,从而允许您在以后的执行中调用它



作为对您最近评论的回应:您可能可以在单元测试开始执行后使用工厂函数来生成所需的类。这可能与使用元类的想法配合得很好。

因此,您有一个类a(),并且希望在其上提供一些来自第三方类B()的方法?@rob cowie是的,就是这样。最常见的解决方案是a)子类Class1,或b)在初始化Class2时通过传递Class1的实例来包装Class1。你有什么理由不能做这两件事吗?@Katrielex,没有。这就是为什么我要求解释为什么它们不能被使用。这将有助于理解需求是什么。修改mro看起来很漂亮,但除非有充分的理由,否则是不明智的。@Rob我正在为Google App Engine应用程序编写单元测试,为了让它们正常工作,我需要做一些sys.path魔术。我想将Django单元测试库中的一些有用函数包含到我的自定义单元测试中。但是在单元测试建立之前,我不能使用Django。换句话说,在运行单元测试之前,我无法导入我想要使用的类,到那时,按照您建议的方式更改类定义已经太迟了。尝试直接修改_mro_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。在这个过程中,使用mro()修改它也为时过早。但是,im_func正是我想要的!我喜欢使用
im\u func
。我可以发誓不久前我使用了修改mro的技巧。哦,好吧。@Shane:我记得我当时在想什么:你可以修改
\uu base\uu
属性。这两个类都从基继承的原因是Python中的一个错误/问题,涉及修改直接从
对象继承的类的
\uuuuuuuuuuuuuu