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

问题描述:

我有两个一起运行的文件,一个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 

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

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

我该如何知道什么时候应该将其作为一种静态方法?

+0

不是Python,但[这个答案](http://stackoverflow.com/questions/2671496/java-when-to-use-static-methods)应该帮助你考虑。 – tyteen4a03

+0

啊,我记得我读过的文章/文章是在谈论/使用Python语言...... – dissidia

+0

我强烈推荐Raymond Hettinger的46分钟的PyCon 2013演讲,“[Python的班级开发工具包](https://www.youtube.com /手表?ν= HTLu2DFOdTg)”。他是Python的核心开发人员之一,他的讲课总是很有趣,而且内容翔实。这个演示了Python类的许多特性背后的“原因”,包括'@ staticmethod'和'@ classmethod'。 –

静态方法允许你使用它没有一个类的实例。 这样做的副作用是静态方法不能使用任何附加到自身的东西。

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 

据我知道这不是好的做法在单一类的静态方法和正常的人混,但也有在那里它可能是有意义的情况。

+0

嗯..如果我错了,请纠正我。如果要使用静态方法,是否需要'self',例如。 'def get_calories(self)'? – dissidia

+0

@dissidia - 不,因为你不需要实例化obj来使用静态方法 – ryugie

+0

是的,我们不能在static方法中使用自变量,幸运的是,我们仍然可以使用包含描述符的类内定义的属性。 –

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

不管被称为静态方法和类方法的方式(你可以节省内存,并且使用静态方法快速,因为你不必将此方法绑定到特定的类实例)。

在这里,我将讨论更多设计模式

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

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

至于你的情况,我们认为在以下几个方面:

  • 如果你把它当作背景下,情境,正如其名称所示,每个 背景下应包含的内在价值和状态。所以这里的静态方法是 不合适。
  • 如果你把它看作两种不同的策略,你应该使用静态方法。
  • 所以哪个更好:我建议您将两种设计模式结合在一起:使用策略来处理不同的逻辑,并使用称为上下文的新类来保存内部状态和值以为策略提供材料。此外,你的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() 
+0

“class MainWindow”不被视为基类? – dissidia

+0

不,MainWindow只是一个客户端,它使用你的上下文实例。基类表示它充当ur context的父项,并且您的上下文可以重用您的基类通用方法或声明。 –

+0

有什么机会,如果你能给我一个例子吗? – dissidia

我个人的原则是:

  1. 如果我有开始变得过长或难以阅读的方法, 我会尝试将它重构为更小的块。我可能会尝试创建一些其他方法并将它们之间的逻辑分开。如果其中任何一个 没有使用self,但在对象之外是有意义的,我将把它变成一个函数,否则我将保留它作为方法并应用@static_method装饰器。

  2. 在极少数情况下,应该从类中调用某个方法,我会将其设置为类方法:例如,当我有类似MyClass.create_new_instance_from_json(json_string)的东西时。