我有一些简单的装饰器,它有一个参数:
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
这似乎有效,但我感觉它太老套了。我错过了什么吗?我真正的装饰器计算执行时间并将其存储在数据库中,并且它在许多其他类似的地方使用,因此内联它不是一个选项。
实现此目的的一种更简洁的方法是将实例属性的名称传递给装饰器,并从传递给
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