繁体   English   中英

在类中使用装饰器访问self中的属性

[英]Using decorator in a class to access an attribute in self

我有一个为顺序数据处理管道提供一些通用结构的类。 我想定时执行一个方法,并将其保存到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定义中的参数,但这会导致另一个错误。 有没有一种从修饰方法访问属性的简单方法?

您的@time_step()装饰器不是绑定方法,当@time_step运行时,它只是一个函数对象。 在函数中没有定义self ,在此装饰器返回的包装器中也没有定义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

请注意,由于f也未绑定,因此必须将self参数传递给f()调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM