何时知道将方法转换为静态方法

时间:2017-03-09 23:32:03

标签: python static-methods

我有两个一起运行的文件,一个ui文件和一个util文件。

这是UI文件:

import util
class MainWindow(object):
    ...
    def method_context_callback(self, *args):
        if args[0] == 'M1':
            self.ctx = utils.M1Context(...)
            self.ctx.run_context()
        elif args[1] == 'M2':
            self.ctx = utils.M2Context(...)
            self.ctx.run_context()

这是Util文件:

class M1Context(object):
    def __init__(self):
        ...
    def run_context(self):
        # Do something when Method01 is used

class M2Context(object):
    def __init__(self):
        ...
    def run_context(self):
        # Do something when Method02 is used

是否需要在run_context中将utils.py方法作为静态方法?在我的UI中,有两个按钮,分别用于Method01和Method02,用户可以在UI处于活动状态时随时使用按钮。

我问过这个问题是因为我在网上阅读的时候,有人提到它可以考虑。说实话,我对@staticmethod并不是很熟悉,因为我通常以这种格式编写代码。

我如何知道何时以何种情况将其作为静态方法?

3 个答案:

答案 0 :(得分:1)

静态方法允许您在没有类实例的情况下使用。 这样做的副作用是静态方法不能使用附加到self的任何东西。

class Banana:
    def __init__(self, age):
        self.age = age

    @staticmethod
    def get_calories():
        return 88.7

    def get_age():
        return self.age;

Banana.get_calories()  # Is valid
Banana.get_age()  # will not be valid

banana = Banana(age=2)
banana.get_age()  # valid
banana.get_calories() # valid

据我所知,在一个班级中混合使用静态方法和普通方法并不是一个好习惯,但有些情况可能会有意义。

答案 1 :(得分:1)

对于是否使用静态方法没有严格的界限。

无论作为静态方法调用的方法与类方法之间的区别如何(您可以节省内存并快速使用静态方法,因此您不必将此方法绑定到特定的类实例)。

在这里,我将详细讨论设计模式

理想情况下,静态方法意味着此函数应该是无状态的,它声明它应该像一个函数一样,每次传递相同的输入时,我们得到相同的输出。实例捕获的内部状态不会影响静态方法的逻辑和结果。

这就是为什么在策略设计模式中,策略类通常被实现为带有一堆静态方法的所谓静态类。

至于您的情况,请考虑以下方式:

  • 如果您将其视为上下文,则对于上下文,如名称所示,每个 上下文应包含内在值和状态。所以这里的静态方法是 不合适。
  • 如果您将其视为两种不同的策略,则应使用静态方法。
  • 所以哪个更好:我建议将两种设计模式结合在一起:使用策略处理不同的逻辑,并使用一个名为context的新类来保存内部状态和值,为策略提供材料。此外,你的M1,M2类还应该有一个基类,它可以利用面向对象的设计。
from abc import ABCMeta, abstractmethod


class ContextBase(object):
    __metaclass__ = ABCMeta

    def __init__(self):
        pass

    @abstractmethod
    def run_context(self):
        print 'this is logic inside of base'

    @staticmethod
    def step_a():
        pass

    @staticmethod
    def step_b():
        pass

class M1Context(ContextBase):
    def __init__(self):
        super(M1Context, self).__init__()

    def run_context(self):
        super(M1Context, self).run_context()
        print 'logic inside of subclass'
        super(M1Context, self).step_a()
        super(M1Context, self).step_b()


m1 = M1Context()
m1.run_context()

答案 2 :(得分:1)

我的个人规则是:

  1. 如果我的方法开始变得太长或者难以阅读, 我会尝试将它重构成更小的块。我可能会尝试创建一个 很少有其他方法,并将逻辑分开。如果有的话 不使用self但在对象之外有意义,我会转向 它变成了一个函数,否则我会把它作为一个方法并应用@static_method装饰器。

  2. 在应该从类调用方法的极少数情况下,我会使它成为一个类方法:例如当我有MyClass.create_new_instance_from_json(json_string)之类的东西时。