繁体   English   中英

在类级别使用装饰器注册方法

[英]Registering methods with decorator at class level

我希望能够在课程级别注册/返回方法。 我能找到的最接近的答案是: 使用装饰器自动注册类方法 ,除了它以全局寄存器为中心,我正在寻找下面的类特定的东西。

码:

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_ ,因此很可能无法查看方法名称。 我正在试图弄清楚如何应用于各种情况,所以只是寻找'report_'在这种情况下不起作用。

您可以像这样声明一个Reporter类,并将实例用作类属性。 我使用__call__覆盖来缩短装饰器,但你可以命名函数report并将方法装饰为@report.report

class Reporter:
    def __init__(self):
         # Maintain a set of reported methods
        self._reported = set()

    def __call__(self, fn, *args, **kwargs):
        # Register method
        self._reported.add(fn.__name__)
        def decorate(*args, **kwargs):
            return fn(*args, **kwargs)
        return decorate    

class ExampleClass:
    report = Reporter()

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

    @report
    def report_x(self):
        return

    @report
    def report_y(self):
        return

    def method_z(self):
        pass

事实证明这与Mach_Zero的答案相似。 所以关键的区别,这会返回方法,而不是方法名称,并且使用__iter__稍微简化了get_reports()的实现。

码:

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

暂无
暂无

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

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