Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中动态地将方法绑定到类实例_Python_Dynamic_Metaprogramming - Fatal编程技术网

在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()