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

时间:2012-04-03 14:39:01

标签: 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)

3 个答案:

答案 0 :(得分:2)

我认为这回答了你的问题:

In [2]: f = 1 .__add__

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

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

答案 1 :(得分:1)

我不明白这个用例 - 在我看来,简单,简单,惯用的方法就是传入一个对象。

但是:程序到界面,而不是实现。只假设对象具有您需要的方法 - 不要触摸内部或任何其他方法。

答案 2 :(得分:1)

通过运行自己的代码,您可以看到正在尝试的工作正常。 :)

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

在旁注中,__getattr__()不应以无效的属性名称静默返回None。更好地利用这个:

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