[英]Using decorator in a class to access an attribute in self
I have a class which provides some generic structure for a sequential data processing pipeline. 我有一个为顺序数据处理管道提供一些通用结构的类。 I would like to time the execution of a method, and save that to a dictionary attribute of self ( self.timings
). 我想定时执行一个方法,并将其保存到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']()
I can instantiate a Pipeline and add a step to it: 我可以实例化管道并向其添加一个步骤:
pipeline = Pipeline()
@pipeline.step('example_func')
def example_func():
for i in range(10000):
pass
return 'Completed!'
But when I attempt to run pipeline.example_method()
, it cannot access self
: 但是当我尝试运行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
I have tried adding self
to the parameters in the time_step
definition, but that causes another error. 我尝试将self
添加到time_step
定义中的参数,但这会导致另一个错误。 Is there a straightforward way of accessing attributes from a decorated method? 有没有一种从修饰方法访问属性的简单方法?
Your @time_step()
decorator is not a bound method, when @time_step
runs, it is just a function object. 您的@time_step()
装饰器不是绑定方法,当@time_step
运行时,它只是一个函数对象。 No self
is defined in the function, nor is it defined in the wrapper that this decorator returns. 在函数中没有定义self
,在此装饰器返回的包装器中也没有定义self
。
If you use time_step()
only on methods, then you can count on the returned wrapper function being bound (it's just another function object in the class body in that case, so is treated like any other function attached to a class and looked up on the instance): 如果仅在方法上使用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
Note that you do have to pass the self
argument on to the f()
call, since f
is also not bound. 请注意,由于f
也未绑定,因此必须将self
参数传递给f()
调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.