Я изменил 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.
Существует ли принятый и / или рекомендуемый способ создания таких декораторов-членов класса для методов класса, которые были бы менее противоречивыми и менее fr agile?
Для Для минимального воспроизводимого примера , ...
можно считать оператором 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