繁体   English   中英

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

[英]Modifying a class attribute via method decorator

我有一堂课,看起来像这样:

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]}

目前我有这个( datadefaultdict ):

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函数装饰器简单地用适当的函数属性标记方法,然后使用类装饰器从所有标记的对象构建data字典。方法。

您不能这样做,因为该类对象尚不存在。

您可能可以通过创建一个具有@classmethod的基类来用作子类中的装饰器,或者将一个东西存储在其他地方的装饰器以及一个类装饰器或元类,该装饰器或元类稍后将存储复制到该类的data属性中,从而执行类似的操作。

好吧,实际上,在不知道您的实际目标是什么的情况下,以及是否使用Py2或Py3(以及您是否只关心CPython或任何Python),都很难知道该建议什么。

暂无
暂无

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

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