2012-01-22 44 views
3

我建立的,將在項目中經常重複使用各種功能的庫。每個函數都是無狀態的(創建時不需要參數,並且沒有任何內存)。一些功能使用他人。蟒蛇:無狀態的函數庫設計

這些功能將被繞過作爲該項目的其餘參數。

以下方法哪個好?

1.定義某個模塊中的所有函數爲全局函數:

def f1(x): 
    # use x 

def f2(x): 
    # use x and f1 

2.Define的所有功能,如類的方法,並安排在一個層次中的類基礎上使用:

class F1: 
    def __call__(x): 
    # use x 

f1 = F1() 

class F2(F1): 
    def __call__(x): 
    # use x and f1 

f2 = F2() 

我甚至考慮過選項2的原因是我的一些功能有一些共同之處。例如,通過調用f1功能f2f3f11全部啓動。我想我可能想要做這樣的事情:

class F1: 
    def __call__(self, x): 
    self.f1(x) 
    self.calc(x) 
    def f1(self, x): 
    # do something 
    # don't define calc here; F1 is abstract base class 

class F2(F1): 
    def calc(self, x): 
    # do something 

class F3(F1): 
    def calc(self, x): 
    # do something 
+3

你甚至在哪裏做了2的想法? –

+0

@FrancisAvila:看到我更新的問題來解釋我的想法。 – max

+0

你是否想要讓'F2'和'F3'擴展'F1'?這不是代碼所說的...... –

回答

2

選項1是簡單了很多。選項2是不必要的複雜!

另一項建議,可能使測試更加簡單:

1.1。將它們全部定義爲一個模塊中單個類的方法。根據需要使用@staticmethod和@classmethod裝飾器。這可以使他們更容易用mock替代,或者稍後通過提供新的類或子類來替代替代實現。

spam.py:

class Spam(object): 
    @staticmethod 
    def f1(x): 
    # use x 

    @classmethod 
    def f2(cls, x): 
    # use x and cls.f1 

這仍然是比較複雜的,所以你可能只是想用選項1,堅持,直到你有一個需要針對以上。

+0

您使用'@ classmethod'提出的建議與我正在考慮的類似。我不想強迫所有的東西都是'@ classmethod',因爲我想有一天我可能想爲一個函數添加一個狀態;因爲無論如何我都在寫這些類,爲什麼不留下那種潛在需求的靈活性呢? – max

+0

有些方法可以用類或對象替換函數,如果它變得有必要具有狀態而不更改API。 – kindall

+0

@ kindall:啊,這是真的。我沒有想到這一點。這很簡單 - 只需使用__call__'? – max

2

如果你不存儲在你的類,數據,你不會是,如果這些是無狀態的功能,我看不到任何一點使用它們。 Python允許您在模塊級精確定義函數,這樣您就不必使用類,除非您真的需要類的功能。

3

如果需要幾個函數在開始執行一些常用的代碼和/或結束時,您可以把常用的代碼在一個裝飾,如explained here