2017-08-24 58 views
0

我在我的python包中使用了一個繼承機制,我的所有類都從基類繼承,所以我不必重新定義在多個類中使用的方法的副本。這裏是抽象形式的策略:這個繼承模式適合於構建一個python包嗎?

class Base(object): 
    def __init__(self, **kwargs): 
     self.kwargs = kwargs 
     self.update_properties(self.kwargs) 


    def update_properties(self, new_properties): 
     for k in new_properties: 
      try: 
       getattr(self, k) 
      except AttributeError: 
       setattr(self, k, new_properties[k]) 


    @staticmethod 
    def check_integrity(allowed, given): 
     for key in given: 
      if key not in allowed: 
       raise Exception('{} not in {}'.format(key, allowed)) 

class A(Base): 
    def __init__(self, **kwargs): 
     super(A, self).__init__(**kwargs) 

     ##class specific keyword arguments 
     self.default_properties = {'a': 1, 
            'b': 2} 

     ## now update the class properties from defaults 
     self.update_properties(self.default_properties) 

     ''' 
     check the integrity of the user input 
     (i.e. i'm enforcing the restriction that kwargs supplied by 
     a user are predefined in the self.default_properties dict. 
     ''' 
     self.check_integrity(self.default_properties.keys(), kwargs.keys()) 


class B(A): 
    def __init__(self, **kwargs): 
     super(B, self).__init__(**kwargs) 
     super(B, self).check_integrity() 

     self.default_properties = {'c': 3, 
            'd': 4} 

     self.update_properties(self.default_properties) 

>>> base = Base() 
>>> print base.__dict__ 
output [0]: {'kwargs': {}} 

>>> a = A(a=4) 
>>> print a.__dict__ 
output [1]: {'a': 4, 'default_properties': {'a': 1, 'b': 2}, 'b': 2, 'kwargs': {'a': 4}} 

>>> b = B(d=5) 
output [2]: Exception: d not in ['a', 'b'] 

正如你可以看到這個代碼工作得很好,直到我們開始「鏈接」繼承(基地< --a < --B))。這裏的問題是,儘管我在我的代碼中使用了**kwargs,但我仍然想驗證用戶輸入(我使用基類中的check_integrity方法執行此操作)。由於kwargs from B不在的allowed屬性中,當初始化B時,A調用check_integrity方法並引發錯誤。

我的問題是:

1)可以(應該)這段代碼被修改,使得像B類也可以使用check_integrity方法和什麼選擇?我試過覆蓋B中的check_integrity方法,因爲錯誤仍然在A中,所以無法正常工作。我當然可以不檢查這個類中的用戶輸入,但這似乎有些不完整。 2)由於我已經發現了一個無法預料的設計問題,因此知道其他人(更有經驗的程序員)是否能夠以這種方式使用繼承來看到任何其他漏洞/陷阱,這將會使其不適用於其他應用程序用於構建一個python包? (對於這裏的更一般的問題抱歉,但因爲我是自學的,所以SO基本上是我唯一的老師)

我希望這是明確的,在此先感謝。

回答

0

另一種解決方法共享問題的方法是使用mixins。 Python支持多重繼承,因此您可以定義包含要在子類之間共享的方法的類。該方法也將按照其他繼承規則的預期行事。 實施例:

class Mixin(object): 
    def shared_method(self): 
     self.dostuff() 

class A(SuperClass, Mixin): 
    pass 

A現在將有內Mixin定義的所有方法。 小心不要做那些會混淆對象屬性的東西,比如在mixin的方法中定義__init__,以避免干擾其他超類的行爲:)