2017-03-09 78 views
0

我有兩個一起運行的文件,一個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'。 –

回答

1

靜態方法允許你使用它沒有一個類的實例。 這樣做的副作用是靜態方法不能使用任何附加到自身的東西。

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方法中使用自變量,幸運的是,我們仍然可以使用包含描述符的類內定義的屬性。 –

1

關於是否使用靜態方法沒有嚴格的界限。

不管被稱爲靜態方法和類方法的方式(你可以節省內存,並且使用靜態方法快速,因爲你不必將此方法綁定到特定的類實例)。

在這裏,我將討論更多設計模式

理想情況下,靜態方法意味着這個函數應該是無狀態的,它聲明它應該像一個函數一樣,每次傳遞相同的輸入時,我們得到相同的輸出。實例不會捕獲可能影響靜態方法的邏輯和結果的內部狀態。

所以這就是爲什麼在策略設計模式中,策略類通常被實現爲具有一堆靜態方法的所謂的靜態類。

至於你的情況,我們認爲在以下幾個方面:

  • 如果你把它當作背景下,情境,正如其名稱所示,每個 背景下應包含的內在價值和狀態。所以這裏的靜態方法是 不合適。
  • 如果你把它看作兩種不同的策略,你應該使用靜態方法。
  • 所以哪個更好:我建議您將兩種設計模式結合在一起:使用策略來處理不同的邏輯,並使用稱爲上下文的新類來保存內部狀態和值以爲策略提供材料。此外,你的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

我個人的原則是:

  1. 如果我有開始變得過長或難以閱讀的方法, 我會嘗試將它重構爲更小的塊。我可能會嘗試創建一些其他方法並將它們之間的邏輯分開。如果其中任何一個 沒有使用self,但在對象之外是有意義的,我將把它變成一個函數,否則我將保留它作爲方法並應用@static_method裝飾器。

  2. 在極少數情況下,應該從類中調用某個方法,我會將其設置爲類方法:例如,當我有類似MyClass.create_new_instance_from_json(json_string)的東西時。