在Python中动态绑定方法到类实例
from moduleA import ClassA
A = ClassA()
aout = A.calling_method()
假设我在 moduleA.py
里定义了一个类,现在我想给这个类添加一个方法。这个方法需要通过某种加载器方法来实现,这个加载器会接收第二个模块的名字,以及在那个模块里定义的方法,以便将其绑定到我的类上。
class ClassA(object):
def __init__(self,config):
super(ClassA, self).__init__()
self.a = 1
self.b = 2
self.meth1 = self. bind_method(config)
def bind_method(self,config):
# load method
<return method defined in config as a str 'moduleB.meth2'>
def calling_method():
return self.meth1()
在 moduleB.py
中定义的方法大概是这样的:
def meth2(self):
return self.a + self.b
我的目的是希望在绑定后,能够让 meth2
访问到 ClassA
的类变量。这样,当你调用类似 A.calling_method()
的时候,就能正确地调用在 moduleB.py
中定义的方法。
我看到在 StackOverflow 上有些回答提到,可以在实例化 ClassA
后使用 types.MethodType
来进行这种绑定,但我还没有找到如何在类定义内部进行绑定的方法,这样在类实例化时就能自动完成。
如果有人能给我一些关于 bind_method
方法应该怎么写的建议,我将非常感激。
4 个回答
3
因为meth2()是一个函数,所以它可以被看作是一个描述符。你可以通过调用__get__()这个方法来绑定它。
def meth2(self):
return self.a + self.b
class ClassA(object):
def __init__(self,config):
super(ClassA, self).__init__()
self.a = 1
self.b = 2
self.meth1 = config.__get__(self, ClassA)
c = ClassA(meth2)
print c.meth1() #correctly prints 3
5
跳过那些我不太明白的配置部分,绑定的内容看起来是这样的:
from moduleB import meth2
ClassA.meth1 = meth2
这里最重要的是,你绑定的是类,而不是某个具体的实例。这样,如果你在一个实例上调用 meth1
方法,它会自动把这个实例作为第一个参数传进去。
7
import sys
import types
def getobj(astr):
"""
getobj('scipy.stats.stats') returns the associated module
getobj('scipy.stats.stats.chisquare') returns the associated function
"""
try:
return globals()[astr]
except KeyError:
try:
return __import__(astr, fromlist=[''])
except ImportError:
modname, _, basename = astr.rpartition('.')
if modname:
mod = getobj(modname)
return getattr(mod, basename)
else:
raise
class ClassA(object):
def __init__(self, methpath):
super(ClassA, self).__init__()
self.a = 1
self.b = 2
self.meth1 = types.MethodType(getobj(methpath), self)
a = ClassA('moduleB.meth2')
print(a.meth1())
# 3
当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。