python - 通过方法装饰器修改类属性

标签 python metaprogramming

我有一个看起来像这样的类:

class Test(object):
    data = {}

    @add_to_data(1)
    def method_1(self, x, y):
        pass

    @add_to_data(1, 2, 3)
    def method_2(self, x, y):
        pass

    @add_to_data(5, 6, 7)
    def method_3(self, x, y):
        pass

我希望它在“导入时”类的 data 属性是:

>>> Test.data
{'method_1': [1], 'method_2': [1, 2, 3], 'method_3': [5, 6, 7]}

目前我有这个(data 是一个defaultdict):

def add_to_data(*items):
    def decorator(func):
        for item in items:
            name = func.__name__
            cls = ??
            cls.data[name].append(item)
        return func
    return decorator

但是我不知道如何获取类对象。有帮助吗?

最佳答案

它不是特别干净,但您可以使用 sys._getframe() 检查调用范围(装饰器将在类定义的上下文中调用,其中 data 是局部变量。

所以像下面这样的东西应该可以工作:

import sys

def add_to_data(*items):
    def decorator(func):
        name = func.__name__
        data = sys._getframe(1).f_locals.get('data')
        if data is not None:
            data.setdefault(name, []).extend(items)
        return func
    return decorator

如果你不想依赖于 sys._getframe 或者想要更明确的东西,你可以让你的 @add_to_data 函数装饰器简单地用适当的标记方法function 属性,然后使用类装饰器从所有标记的方法构建 data 字典。

关于python - 通过方法装饰器修改类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13871769/

相关文章:

python - 在Python中循环不按顺序的列表

python - 如何加速我在 hadoop 上的 tensorflow 执行?

python - 如何将 sympy codegen 与包含已实现函数的表达式一起使用

Ruby 元类类层次结构

ruby - 使用什么机制允许从该范围调用 ruby​​ root 范围中定义的方法?

python - 如何在 Python 中找出方法的数量

python - 如何识别哪个包出现 AttributeError : 'module' is referring to?

python - 如何获得图像/超链接格式的聊天机器人响应?

julia - 制作宏以将函数标记为已弃用

javascript - javascript 的 `new` 运算符能否返回可调用对象?