我更改了一个class
,它有一个必须在运行许多其他函数之前运行的函数。“优先于他人”功能现在是一个装饰器。但我提出的语法似乎非常不直观
过去是这样的:
class Session:
def __init__(self, ts):
self.tempo_throttlers = [TempoThrottler(t) for t in ts]
...
def _wait_on_throttlers(self):
for th in self.tempo_throttlers:
if not th.isallowed():
time.sleep(th.mustwait())
th.consume()
...
def request1(self):
self._wait_on_throttlers()
...
def request2(self):
self._wait_on_throttlers()
...
现在是这样的:
class Session:
def __init__(self, ts):
self.tempo_throttlers = [TempoThrottler(t) for t in ts]
...
def _wait_on_throttlers(self):
for th in self.tempo_throttlers:
if not th.isallowed():
time.sleep(th.mustwait())
th.consume()
...
def _throttled(f):
def inner(self, *args, **kwargs):
self._wait_on_throttlers()
return f(self, *args, **kwargs)
return inner
@_throttled
def request1(self):
...
@_throttled
def request2(self):
...
而且,虽然我认为这个装饰器的使用使代码更加清晰,但是这个装饰器的实现需要做一些工作。它也很脆弱,很难阅读。例如,如果内部返回行return f(self, *args, **kwargs)
更改为return self.f(*args, **kwargs)
,则它将不再工作
这似乎与类元素的编译顺序有关。我还担心这会在Python的未来版本中中断。我正在使用Python 3.6.8
有没有一种公认的和/或推荐的方法使类方法的类成员装饰器不那么违反直觉,也不那么脆弱
为了最小的可重复性示例,可以将...
视为pass
语句,类TempThrottler
可以定义如下(这不是实际实现,但足以满足上面的示例):
class TempoThrottler:
def __init__(self, t):
pass
def isallowed(self):
from random import randint
return (True, False)[randint(0,1)]
def mustwait(self):
return 1
def consume(self):
pass
乍一看,为了解决这个问题,这可能更复杂
我将使装饰器参数化,并将其移出课堂。然后,可以将专门用于特定预调用方法的decorator实例分配给类变量。然后这个类变量可以用作实际的装饰器
下面是一个可运行的示例,演示了我的建议,即如何将decorator函数完全移出类:
相关问题 更多 >
编程相关推荐