在类级别向装饰器注册方法

时间:2018-09-16 23:53:58

标签: python python-3.x metaprogramming decorator

我希望能够在类级别注册/返回方法。我能找到的最接近答案是:Auto-register class methods using decorator,除了它以全局寄存器为中心,并且我在下面查找与该类有关的某些东西。

代码:

static int[] CloneArray(int[] arr)
{
    int[] ret = new int[arr.Length];
    for (int i = 0; i < arr.Length; ++i) ret[i] = arr[i];
    return ret;
}

我希望class ExampleClass: def get_reports(self): # return list of all method names with @report decorator pass def report(self): # decorator here pass @report def report_x(self): return @report def report_y(self): return def method_z(self): pass 返回ExampleClass.get_reports()的地方。

并非所有报告都以['report_x', 'report_y']开头,因此可能无法仅查看方法名称。我正在尝试找出如何将该方法应用于各种情况的方法,因此仅在这种情况下寻找report_无效。

2 个答案:

答案 0 :(得分:4)

您可以像这样声明一个Reporter类,并将实例用作类属性。我使用ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password' 覆盖来缩短修饰符,但是您可以命名函数__call__并将方法修饰为report

@report.report

答案 1 :(得分:1)

这与Mach_Zero's answer类似。因此,关键的不同之处在于,这将返回方法,而不是方法名称,并且get_reports()的实现通过使用__iter__会更简单。

代码:

class Reports:

    def __init__(self):
        self.reports = []

    def __call__(self, func):
        self.reports.append(func)
        return func

    def __iter__(self):
        return iter(self.reports)


class ExampleClass:

    report = Reports()

    @classmethod
    def get_reports(cls):
        # return list of all method names with @report decorator
        return list(cls.report)

    @report
    def report_x(self):
        return

    @report
    def report_y(self):
        return

    def method_z(self):
        pass

测试代码:

print(ExampleClass.get_reports())

结果:

[
    <function ExampleClass.report_x at 0x000000000AF7B2F0>, 
    <function ExampleClass.report_y at 0x000000000AF7B378>
]