Python的__getattribute__和方法包装器

2 投票
2 回答
2169 浏览
提问于 2025-04-19 05:22

我想在调用某个特定方法之前,先调用一个包装方法,并且这个包装方法需要带上参数。于是我想我得重写一下 __getattribute__ 这个方法。

下面是一个代码示例:

def wrapper(func):
    return func * 2

class A(object):
    def test(self, arg):
        return arg + 1

    def __getattribute__(self, name):
        if name in ['test']:
            return wrapper(super(A, self).__getattribute__(name))
        return super(A, self).__getattribute__(name)

问题在于,当 test 返回值的时候,getattribute 方法会被调用。我想要的是能够在调用 test 的时候,抓住它的参数,并像这样定义包装方法:

def wrapper(func, *args, **kwargs):
    print "do some stuff"
    return func(*args, **kwargs)

2 个回答

1

如果我理解得没错的话,你可以使用一个装饰器。

def wrapper(func):
    def _wrapper(*args, **kwargs):
        return func(*args, **kwargs) * 2

    return _wrapper

class A(object):
    @wrapper
    def test(self, arg):
        return arg + 1
4

使用工厂函数来返回你的包装器:

def decorate(f):
    def wrapper(*args, **kw):
        return f(*args, **kw) * 2
    return wrapper

这里的 fwrapper() 包裹住了,所以在调用的时候它可以访问到名字。

然后在 __getattribute__ 钩子里返回这个:

def __getattribute__(self, name):
    result = super(A, self).__getattribute__(name)
    if name in ('test',):
        return decorate(result)
    return result

当然,你也可以直接把 decorate 作为装饰器应用在 test 上:

class A(object):
    @decorate
    def test(self, arg):
        return arg + 1

撰写回答