创建带有动态参数的装饰器

问题描述 投票:0回答:1

我有一些简单的装饰器,它有一个参数:

def deco(name):
    def outer(f):
        def inner(*args, **kwargs):
            print(name)
            return f(*args, **kwargs)

        return inner

    return outer

还有一个班级:

class A:
    def __init__(self, name):
        self.name = name

    @deco(self.name) # This is my goal
    def foo(self):
        pass

我希望能够创建几个

A
的实例,并且每个实例都有自己的 foo 版本(用
deco(name)
装饰)。

这显然不起作用,因为函数是类作用域,而不是实例作用域。 我考虑了动态方法,例如:

class A:
    def __init__(self, name):
        self.name = name
        A.foo = deco(name)(A._foo)

    def _foo(self):
        pass

但是当我们创建更多实例时就会出现问题。

最后我选择了:

class A:
    def __init__(self, name):
        self.name = name
        self.foo = deco(name)(partial(A._foo, self))

    def _foo(self):
        pass

这似乎有效,但我感觉它太老套了。我错过了什么吗?我真正的装饰器计算执行时间并将其存储在数据库中,并且它在许多其他类似的地方使用,因此内联它不是一个选项。

python inheritance
1个回答
0
投票

实现此目的的一种更简洁的方法是将实例属性的名称传递给装饰器,并从传递给

self
的第一个参数中提取
inner()

def deco(attr):
    def outer(f):
        def inner(self, *args, **kwargs):
            print(getattr(self, attr))
            return f(self, *args, **kwargs)

        return inner

    return outer


class A:
    def __init__(self, name):
        self.name = name

    @deco("name")
    def foo(self):
        pass
© www.soinside.com 2019 - 2024. All rights reserved.