首页 > 解决方案 > 如何定义方法以充当 Python 中同一类中其他方法的装饰器?

问题描述

我正在构建简单的 JSON DB,它具有insert,update等方法get

我知道创建self._write()写入 json 文件并在每个方法中调用它的方法很简单,但是有什么方法可以创建_write所有这些函数的装饰器,但是作为Database的方法?

我试过这个,但我没能把我的手包住:

import pathlib
import json

DATABASE_PATH = pathlib.Path('/home/me/db.json')


class Database:

    def __init__(self):
        self.data = dict()

    def _write(self):
        def decorator(f, *args, **kwargs):
            _response = f(**kwargs)  # I'm assuming this would be `insert` method call ?
            with DATABASE_PATH.open(mode='w', encoding='utf-8') as _db:
                json.dump(self.data, _db, indent=4)  # Calling `f` would modify `self.data`
            return _response

        return decorator

    @_write  # Complaining function `_write` lacks positional argument self, but can't access it ?
    def insert(self, **kwargs):
        if all(k for k in kwargs if k in ('name', 'surname')):  # Insert if contains all values.
            self.data.update(**kwargs)
            return True
        return False  # Insert failed.

是否可以编写类方法来充当装饰器,该装饰器将用于同一类中定义的其他类方法?

标签: pythonclassdecoratorpython-decorators

解决方案


我设法解决了这个问题,但最后我只是选择将_write类提取为常规装饰器函数。

这个解决方案打破了 Python 之禅的许多规则,如果有更好的解决方案我会接受它:

import pathlib
import json

DATABASE_PATH = pathlib.Path('db.json')


class Database:

    def __init__(self):
        self.data = dict()

    def _write(fn):
        def decorator(self, **kwargs):
            _response = fn(self, **kwargs)
            with DATABASE_PATH.open(mode='w', encoding='utf-8') as _db:
                json.dump(self.data, _db, indent=4)
            return _response
        return decorator

    @_write
    def insert(self, **kwargs):
        if all(k for k in kwargs if k in ('name', 'surname')):  # Insert if contains all values.
            self.data.update(**kwargs)
            return True
        return False  # Insert failed.


if __name__ == '__main__':
    db = Database()
    db.insert(name='Dummy-Name', surname='Dummy-Surname')

推荐阅读