У меня есть класс, который предоставляет некоторую общую структуру для последовательного конвейера обработки данных.Я хотел бы рассчитать время выполнения метода и сохранить его в атрибуте словаря self (self.timings
).
from functools import wraps
import time
class Pipeline(object):
def __init__(self):
self.steps = {}
self.timings = {}
# Decorator for adding functions to pipeline
def step(self, step_name):
def step_decorator(f):
self.steps[step_name] = f
return step_decorator
# Decorator for timing a step
def time_step(f):
@wraps(f)
def timed(*args, **kwargs):
start = time.time()
result = f(*args, **kwargs)
end = time.time()
self.timings[f.__name__] = end - start
return result
return timed
@time_step
def example_method(self):
if 'example_func' in self.steps:
self.output = self.steps['example_func']()
Я могу создать конвейер и добавить к нему шаг:
pipeline = Pipeline()
@pipeline.step('example_func')
def example_func():
for i in range(10000):
pass
return 'Completed!'
Но когда я пытаюсь запустить pipeline.example_method()
, он не может получить доступ к self
:
pipeline.example_method()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-54-8204774a5649> in <module>()
----> 1 pipeline.example_method()
<ipython-input-51-ffb2e95a110a> in timed(*args, **kwargs)
21 result = f(*args, **kwargs)
22 end = time.time()
---> 23 self.timings[f.__name__] = end - start
24 return result
25 return timed
NameError: name 'self' is not defined
Я попытался добавить self
к параметрам в определении time_step
, ноэто вызывает другую ошибку.Есть ли простой способ доступа к атрибутам из декорированного метода?