【发布时间】:2021-08-25 09:48:56
【问题描述】:
我有一个对象方法的装饰器:
def wrapper(func):
def _wrapper(self, *a, **kw):
print(self.foo)
return func(self, *a, **kw)
return _wrapper
class Bar:
foo = 1
@wrapper
def baz(self):
print(2)
# This works as expected :)
In [2]: Bar().baz()
1
2
我想为此添加另一层环绕以允许参数:
def wrapper(bla):
def _wrapper(func):
def __wrapper(self, *a, **kw):
print(self.foo + bla)
return func(self, *a, **kw)
return __wrapper
return _wrapper
class Bar:
foo = 1
@wrapper(1)
def baz(self):
print(2)
# which also works great
In [4]: Bar().baz()
2
2
现在,我想要做的是将self 属性作为包装器参数传递,即用类似这样的方式调用它
class Bar:
def __init__(self):
self._foo = 1
@wrapper(self._foo)
def baz(self):
pass
我看到了 2 个选项:
- 使
self._foo全局 - 不要传
self._foo,让装饰器访问self._foo
两者都不好。 (全局可以在我不知情的情况下从另一个地方更改,并且让装饰器访问self._... 意味着装饰器知道它所操作的类)
有什么好办法吗?
【问题讨论】:
-
将属性名作为字符串传递,调用内部时在装饰器中使用
getattr()? -
你不能那样做。当类被定义时调用装饰器,此时不可能有任何个实例。该实例只能在作为参数的内部包装器中访问。您能否就实际用例提供更多背景信息?
-
@IainShelvington 是一种技术解决方案,但是,它遇到了与我的第二个解决方案相同的问题
-
什么是问题?你只是说“两者都不好”。
-
我不太清楚你所说的 “装饰器知道它所操作的类” 是什么意思,但 Iain 的建议是,例如
@wrapper("_foo")仅在特定包装器需要self具有_foo属性时才耦合 - 这是实际 行为 所需的耦合。