在python中动态地将方法绑定到类实例
假设我在在python中动态地将方法绑定到类实例,python,dynamic,metaprogramming,Python,Dynamic,Metaprogramming,假设我在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
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()
要点是,我希望能够编写meth2
,以便在绑定后能够访问ClassA
的类变量。通过这种方式,当您遇到以下情况时:
def meth2(self):
return self.a + self.b
from moduleA import ClassA
A = ClassA()
aout = A.calling_method()
调用A.Calling_method()
正确调用moduleB.py
中定义的方法
我已经在answers on中看到过这种绑定是在使用types.MethodType
实例化ClassA
之后完成的,但是我还不能深入了解如何在类定义内部绑定,以便在实例化类时在内部完成
如果您对
bind\u方法中应该包含的内容有任何建议,我们将不胜感激。跳过我不清楚的配置内容,绑定本身将如下所示:
from moduleB import meth2
ClassA.meth1 = meth2
重要的部分是绑定到类,而不是实例。这样,如果在实例上调用meth1
,它将自动接收该实例作为第一个参数。因为meth2()是一个函数,它是一个描述符,您可以通过调用uu get\uu()方法来绑定它
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
实际上有一种更简单的方法:
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()
config
在这里扮演什么角色?由于当前定义了ClassA
,因此moduleB.py
中的第三行将导致错误…@senderle-config
可能是一个字典,其中包含定义要绑定的方法所在位置的项,或者类似的内容。重要的是指定了其中应该添加到ClassA
的模块和方法。我很困惑,你是在尝试实现类继承吗?我熟悉这种类型的monkey补丁,但这些语义在我的应用程序中不起作用case@JoshAdel,那样的话,我想你应该把标题改为“在python中动态地将方法绑定到类实例。”这可能是您所问的实际问题的正确答案。+1。唯一的问题是,它没有为meth1.im\u class
提供值。我正在研究一个类似的解决方案,包括创建一个classmethod
,比如:def bind\u方法(cls、实例、函数)
,它返回一个方法类型
。这似乎是确保类与实例正确绑定的最优雅的方式…@senderle在研究这个问题时,我遇到了。im\u class
,但它没有正常工作。我很想看看您的解决方案well@unutbu谢谢,这似乎很好rk并做了一些类似于我尝试的事情(types.Method(,self)
),但我正在修改我的str_to_obj
版本。我需要完成您对该帮助器方法的实现,因为其中有些内容我无法立即理解。@senderle:您可以通过向types.MethodType
:types.MethodType(str_to_obj)提供第三个参数来设置meth1.im\u class
(methpath)、self、type(self))
。但是,Python3从types.MethodType
中删除了第三个参数,并且没有检查实例是否属于正确的类。因此,为了Python3的兼容性,我认为最好删除第三个参数。@unutbu,是的,我没有完全阐明我的观点;提供第三个参数正是我想要的很有启发性。但是根据您所说的,删除它是有意义的——我不知道Python 3删除了那个参数。很高兴知道,谢谢!
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()