在将方法作为类外的对象传递时,是否可以保持方法的“边界”

2024-10-03 09:11:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试编写一个库,它将从多个服务端点向容器注册任意服务调用列表。我打算在为每个服务编写的类中实现服务调用。在将服务类中的方法注册到容器时,是否有办法保持这些方法的有界性(这样它们仍然可以访问其所属对象实例的实例数据),或者我必须注册整个对象,然后在容器类中使用__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)

Tags: 方法nameselfregisterdefservicewithargs
3条回答

我不理解这个用例,在我看来,实现这个的简单、惯用的方法就是传入一个对象。你知道吗

但是:程序到接口,而不是实现。只假设对象具有所需的方法,而不必触及内部或任何其他方法。你知道吗

我想这回答了你的问题:

In [2]: f = 1 .__add__

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

将这些函数添加到类中时,不需要使用staticmethod函数,因为它们实际上已经“静态”了。你知道吗

正如您运行自己的代码所看到的那样,您正在尝试做的事情将很好地工作。:)

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

另一方面,对于无效的属性名,__getattr__()不应该自动返回None。最好用这个:

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

相关问题 更多 >