【问题标题】:How do I run a collection of similar methods in a python class?如何在 python 类中运行类似方法的集合?
【发布时间】:2022-01-19 11:50:19
【问题描述】:

我正在处理一个包含数十个“业务逻辑”方法和一些辅助方法的大型 Python 类。最后有一些有趣的代码用于运行所有“calc_metric_*”方法。

有点像的东西:

class CalculateMetrics:
    ...

    def calc_metric_x1(self):
        ...

    def calc_metric_x2(self):
        ...

    def calc_metric_x3(self):
        ...

    def calc_metric_x4(self):
        ...
    
    ...

    def calc_metric_x50(self):
        ...

    def run_all(self):
       method_list = [m for m in dir(self) 
                      if callable(getattr(self, m)) 
                      and m.startswith('calc_metric_')]

       for m in method_list:
           # Call each method
           getattr(self, m)()

使用getattr + 引用方法的名称对我来说似乎不是最佳选择。有没有更好的方法在 Python 中实现这一点?

【问题讨论】:

  • 这对我来说看起来不错,除了我们无法从您可能想要执行的代码中看到的其他内容。您可以添加错误捕获或额外变量以使“calc_metric”部分灵活。
  • 公平地说,代码有效。
  • 但是,如果您认为所有这些方法都不是真正必要的,并且您想消除其中的一些,我看不出它们各自的不同之处以及它们是否有一些共同的东西可以删除其中的一些。
  • 不,它们每个都编码独特的业务逻辑,但非常相关。我找到了一种在每个方法定义周围使用装饰器将它们“添加”到寄存器和/或向方法对象添加属性以使其更明确哪些方法是帮助器以及应该由run_all() 运行的方法方法。

标签: python oop


【解决方案1】:

您可以使用这样的装饰器函数来收集它们:

def calc_metric(func):
    if func not in calc_metric.calc_metric_funcs:
        calc_metric.calc_metric_funcs.append(func)
    return func


calc_metric.calc_metric_funcs = []

然后你需要用@calc_metric装饰所有想要的功能:

    @calc_metric
    def calc_metric_x1(self):
        
        ...

    @calc_metric
    def calc_metric_x2(self):
        ...

    ...

    @calc_metric
    def calc_metric_x50(self):
        ...

而你的run_all()函数会是这样的:

    def run_all(self):
        for f in calc_metric.calc_metric_funcs:
            f(self)

注意calc_metric 函数必须在CalculateMetrics 类之外声明。

【讨论】:

  • 是的,完美。这似乎是最好的方法。
猜你喜欢
  • 2015-11-08
  • 2021-10-21
  • 2017-08-05
  • 2017-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
  • 2014-03-24
相关资源
最近更新 更多