我有一个为顺序数据处理管道提供一些通用结构的类。我想定时执行一个方法,并将其保存到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
定义中的参数中,但这会导致另一个错误。是否有一种从修饰方法访问属性的简单方法?
答案 0 :(得分:1)
您的@time_step()
装饰器不是绑定方法,运行@time_step
时,它只是一个函数对象。在函数中没有定义self
,在此装饰器返回的包装器中也没有定义。
如果仅在方法上使用time_step()
,则可以依靠返回的包装函数进行绑定(在这种情况下,它只是类体内的另一个函数对象,因此与附加到函数上的任何其他函数一样)类并查看实例):
def time_step(f):
@wraps(f)
def timed(self, *args, **kwargs):
start = time.time()
result = f(self, *args, **kwargs)
end = time.time()
self.timings[f.__name__] = end - start
return result
return timed
请注意,由于self
也未绑定,因此必须将f()
参数传递给f
调用。