繁体   English   中英

将方法作为对象传递到类之外时,是否可以保持方法的“绑定性”

[英]Is it possible to maintain “boundness” of a method when passing it as an object outside its class

我正在尝试编写一个库,该库将注册从多个服务端点到容器的任意服务调用列表。 我打算在每个服务编写的类中实现服务调用。 将方法注册到容器时,是否有办法维护服务类中方法的有界性(因此它们仍然可以访问其拥有的对象实例的实例数据),或者必须注册整个对象然后编写某种形式在容器类中使用__getattr__或其他类似方法来访问实例上下文中的方法?

容器:

class ServiceCalls(object):
    def __init__(self):
        self._service_calls = {}
    def register_call(self, name, call):
        if name not in self._service_calls:
            self._service_calls[name] = call
    def __getattr__(self, name):
        if name in self._service_calls:
           return self._service_calls[name]

服务:

class FooSvc(object):
    def __init__(self, endpoint):
        self.endpoint = endpoint
    def fooize(self, *args, **kwargs):
        #call fooize service call with args/kwargs utilizing self.endpoint
    def fooify(self, *args, **kwargs):
        #call fooify service call with args/kwargs utilizing self.endpoint


class BarSvc(object):
    def __init__(self, endpoint):
        self.endpoint = endpoint
    def barize(self, *args, **kwargs):
        #call barize service call with args/kwargs utilizing self.endpoint
    def barify(self, *args, **kwargs):
        #call barify service call with args/kwargs utilizing self.endpoint

实施代码:

foosvc = FooSvc('fooendpoint')
barsvc = BarSvc('barendpoint')
calls = ServiceCalls()
calls.register('fooize', foosvc.fooize)
calls.register('fooify', foosvc.fooify)
calls.register('barize', barsvc.barize)
calls.register('barify', barsvc.barify)
calls.fooize(args)

我认为这可以回答您的问题:

In [2]: f = 1 .__add__

In [3]: f(3)
Out[3]: 4

将这些函数添加到类时,您将不需要staticmethod函数,因为它们实际上已经是“静态的”。

我不了解这种情况的用例-在我看来,完成此任务的简单,简单,惯用的方法是只传递一个对象。

但是 :程序要接口,不能执行。 仅假定对象具有您需要的方法-请勿触摸内部或其他任何方法。

正如您通过运行自己的代码可以看到的那样,您尝试做的事情将正常运行。 :)

对象foosvc.fooize在Python中称为“绑定方法”,它同时包含对foosvc和函数FooSvc.fooize 如果调用bound方法,则对self的引用将作为第一个参数隐式传递。

另外,对于无效的属性名称, __getattr__()不应静默返回None 最好使用这个:

def __getattr__(self, name):
    try:
        return self._service_calls[name]
    except KeyError:
        raise AttributeError

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM