2015-05-11 33 views
0

我工作的一個抽象層到數據庫中,我有一個超類中定義與此類似:覆蓋類方法來定義Kwargs - 哪個是Pythonic?

class Test(): 
    __init__(self, object): 
     self.obj = object 

    @classmethod 
    def find_object(cls, **kwargs): 
     # Code to search for object to put in parameter using kwargs. 

     return cls(found_object) 

我再打破該超成更具體到他們所代表的對象的子類。

class Test_B(Test): 
    # Subclass defining more specific version of Test. 

現在,Test的每個單獨的子類都有預定義的搜索條件。例如,Test_B需要a = 10,b = 30,c =「Pie」的對象。

哪個會更「Pythonic」?從超類使用find_object方法:

testb = Test_B.find_object(a=10, b=30, c="Pie") 

或覆蓋find_object方法期望的a,b,和c作爲參數:

@classmethod 
def find_object(cls, a, b, c): 
    return super().find_object(a=a, b=b, c=c) 

testb = Test_B.find_object(10, 30, "Pie") 
+0

爲什麼不寫調度員函數,選擇正確的類來傳遞kwargs呢? –

回答

0

Test.find_object不打算直接使用,所以我將它命名爲

@classmethod 
def _find_object(cls, **kwargs): 
    ... 

然後讓每個子類中調用它來實現自己的find_object

@classmethod 
def find_object(cls, a, b, c): 
    return super()._find_object(a=a, b=b, c=c) 

當使用super,這是一個好主意,如果覆蓋它保存方法的簽名,因爲你永遠不能對某些哪個類super將retur代理人。

0

skilsuper - 你說得對

Explicit is better than implicit

然而,這並不意味着第一個答案是更好的 - 你仍然可以申請第二解決方案相同的原理:find_object(10, 30, "Pie")是隱含的,但沒有什麼是阻止您使用find_object(a=10, b=30, c="Pie")(您的應使用)。

第一種解決方案存在問題,因爲您可能會忘記參數(例如,find_object(a=10, b=30))。在這種情況下,第一個解決方案會讓它滑動,但第二個解決方案將發出TypeError,表示您缺少一個參數。

+0

公平點。兩者都是運行時錯誤,儘管(大概find_object會拋出'ObjectNotFound'或類似的錯誤),所以我沒有看到增加的複雜性帶來的好處。 – skolsuper

+0

我不知道我理解你。如果在第二種情況下意外使用了'find_object(a = 10,b = 30)',它將不會是運行時錯誤。我試過了,我得到了'TypeError:find_object()需要4個參數(給出3個)' – tennabey

+0

我的壞,再次錯誤:( - 編輯:我剛剛嘗試過,它是一個運行時錯誤,您使用IDE嗎? – skolsuper