2

我的代码中实现了很多类。现在我意识到,对于为所有这些类调用的每个方法,我需要添加一行:

with service as object:

所以我正在尝试使用代理模式来自动完成这项工作,这是我的示例代码

class A(object):
    def __init__(self, name):
        self.name = name
    def hello(self):
        print 'hello %s!' % (self.name)
    def __enter__(self):
        print 'Enter the function'
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        print 'Exit the function'
class Proxy(object):
    def __init__(self, object_a):
#        object.__setattr__(self, '_object_a', object_a)
        self._object_a = object_a

    def __getattribute__(self, name):
        service = object.__getattribute__(self, '_object_a')
        with service as service:
            result = getattr(service, name)
        return result    

if __name__=='__main__':
    a1 = A('A1')
    b = Proxy(a1)
    b.hello()
    a2 = A('A2')
    b = Proxy(a2)
    b.hello()

一切正常,我有输出:

Enter the function A1
Exit the function A1
hello A1!
Enter the function A2
Exit the function A2
hello A2!

但这并不完全是我需要的,因为我需要的是相当于:

with a1 as a1:
    a1.hello()

我必须有输出:

Enter the function A1
hello A1!
Exit the function A1
Enter the function A2
hello A2!
Exit the function A2

我需要什么才能得到这个结果?谢谢

4

2 回答 2

8

我会使用装饰器:

class Proxy(object):
    def __init__(self, object_a):
        self._object_a = object_a

    def decorateEnterExit(self, obj, f):
        def inner(*args, **kwargs):
            with obj as _:
                return f(*args, **kwargs)
        return inner

    def __getattribute__(self, name):
        obj = object.__getattribute__(self, '_object_a')
        dee = object.__getattribute__(self, 'decorateEnterExit')
        return dee(obj, getattr(obj, name))

这样,只有在执行函数时才会评估 with 。您执行此操作的方式将首先评估 with (包括退出它),然后将返回该函数以进行调用。现在我们返回一个函数,该函数本身将进入 with 并在其中调用该函数。

>>> Proxy(A('Ax')).hello()
Enter the function
hello Ax!
Exit the function

请注意,您需要self在您的__enter__方法中返回A

def __enter__(self):
    print 'Enter the function'
    return self
于 2013-03-07T11:43:58.677 回答
0

您的方法中缺少一个 return 语句,它应该返回您的 class( )__enter__的一个实例。self

至于问题,在您的Proxy中,很可能在上下文关闭后评估该结果。试试这个看看你实际返回什么 - 是一个绑定方法:

def __getattribute__(self, name):
    service = object.__getattribute__(self, '_object_a')
    with service as service:
        result = getattr(service, name)
        print result
    return result

这将显示

Enter the function
<bound method A.hello of <__main__.A object at 0x022A2950>>
Exit the function

只有 then 方法被调用,在__getattribute__返回它之后。

于 2013-03-07T11:38:11.573 回答