假设我有一个在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
的类变量。这样,当你有类似的东西时:
from moduleA import ClassA
A = ClassA()
aout = A.calling_method()
调用A.calling_method()
可以正确调用moduleB.py
中定义的方法。
在使用ClassA
实例化types.MethodType
之后,我已经在SO的答案中看到了这种绑定,但我无法挖掘如何在类定义中绑定,以便它是在实例化类时在内部完成的。
我们非常感谢您对bind_method
方法应该采用的建议。
答案 0 :(得分:4)
跳过我不清楚的配置内容,绑定本身看起来像这样:
from moduleB import meth2
ClassA.meth1 = meth2
重要的是你要绑定类,而不是实例。这样,如果在实例上调用meth1
,它将自动接收实例作为第一个参数。
答案 1 :(得分:4)
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
答案 2 :(得分:2)
由于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
答案 3 :(得分:-2)
实际上有一种更简单的方法:
class ClassA(object):
def __init__(self,config):
super(ClassA, self).__init__()
self.a = 1
self.b = 2
from moduleB import meth2 as meth1
def calling_method():
return self.meth1()