繁体   English   中英

通过从内部装饰器调用 class 方法修改 class 属性

[英]Modifying class attribute by calling class method from inside decorator

我有很多方法需要打开一些文件(每种方法都有不同),做一些事情,关闭它。 虽然可以在每个方法中打开和关闭文件,但我想知道是否可以通过装饰器来完成,以便装饰器可以将方法作为参数,将数据加载到装饰的 class 正在作用的 obj 属性中.

class Foo:
    def __init__(self, fname):
        self.fname = fname

    def load_file(self):
        with open(self.fname, 'rb') as f:
            self.file_ = pickle.load(f)
    
    def do_some_work(self):
        self.load_file()
        ... # some calculation and so on
        delattr(self, 'file_')

    @loader(self.load_file)
    def do_some_work_decorated(self):
         ... # only some calculation and so on, file loading is done by the defined method in decorator
    

我的问题是这是否可能,是否有更好的方法来解决它?

好吧,您可以做类似的事情,但是您需要将方法的名称传递给装饰器,因为当它用于装饰方法时没有self可以引用 - 当 class 是之后执行其中的代码时未定义。

这就是我的意思:

import pickle

def loader(do_stuff):
    def decorator(method):
        def decorated(self, *args, **kwargs):
            getattr(self, do_stuff)()  # Call specified class method.
            return method(self, *args, **kwargs)  # Then call decorated method.
        return decorated
    return decorator


class Foo:
    def __init__(self, fname):
        self.fname = fname

    def load_file(self):
        with open(self.fname, 'rb') as f:
            self.file_ = pickle.load(f)

    def do_some_work(self):
        self.load_file()
        ... # some calculation and so on
        delattr(self, 'file_')

    @loader('load_file')
    def do_some_work_decorated(self):
        ... # only some calculation and so on, file loading is done by the defined method in decorator
        print(f'{self.file_}')

if __name__ == '__main__':

    # Create a test file.
    with open('foo.pkl', 'wb') as outp:
        pickle.dump(42, outp)

    # See if decorator worked.
    foo = Foo('foo.pkl')
    foo.do_some_work_decorated()  # -> 42

暂无
暂无

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

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