python中动态绑定方法到类实例

发布于 2024-12-28 17:20:00 字数 1040 浏览 2 评论 0原文

假设我在 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 中定义的方法。

在使用 types.MethodType 实例化 ClassA 后,我在 SO 的答案中看到了这种绑定,但我无法弄清楚如何在内部绑定类定义,以便在实例化类时在内部完成。

任何有关 bind_method 方法中应该包含什么内容的建议将不胜感激。

Let's say that I have a class defined in moduleA.py which I want to add a method to, using some sort of loader method that takes a the name of a second module and the method defined there that should be bound

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

where the method defined in moduleB.py looks something like:

def meth2(self):
    return self.a + self.b

The point being that I want to be able to write meth2 to be able to access class variables of ClassA once it is bound. This way, when you would have something like:

from moduleA import ClassA

A = ClassA()
aout = A.calling_method()

Calling A.calling_method() properly calls the method defined in moduleB.py.

I've seen this sort of binding done in answers on SO after ClassA is instantiated using types.MethodType, but I haven't been able to dig up how to bind inside the class definition so that it is done internally when the class is instantiated.

Any suggestions on what should go in the bind_method method would be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

萌面超妹 2025-01-04 17:20:00
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
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
温折酒 2025-01-04 17:20:00

跳过我不清楚的配置内容,绑定本身如下所示:

from moduleB import meth2
ClassA.meth1 = meth2

重要的部分是您绑定到类,而不是实例。这样,如果您在实例上调用 meth1,它将自动接收该实例作为第一个参数。

Skipping the config stuff which wasn't clear to me, the binding itself would look like this:

from moduleB import meth2
ClassA.meth1 = meth2

The important part is that you're binding to the class, not to an instance. This way if you call meth1 on an instance, it will automatically receive the instance as the first argument.

望她远 2025-01-04 17:20:00

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

Since meth2() is a function, it is a descriptor and you can bind it by calling the __get__() method.

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 
满意归宿 2025-01-04 17:20:00

实际上有一种更简单的方法可以做到这一点:

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

There's actually a much simpler way to do this:

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文