2017-01-24 99 views
0

我創建的每個業務規則都放在名爲「rule_definitions」的文件夾中。Python OOP從父類導入子類

我有一個類Rule。它充當所有這些創建的規則的模板,它們可以繼承必要的通用函數。

的文件夾內容的一個例子:

rule_definitions/ 
    discard.py 
    saveValue.py 
    storeValue.py 
    writeToOutput.py 

但是,如果你想創建一個規則的實例,它只是做的很乾淨:

rule = Rule('discard')並有Rule類做進口本身,而不是每次需要加載規則時都找到適當的規則模塊。

例如,rule_definitions.py內容可能是:

from Rule import Rule 

class _discard(Rule): 
    ... 

並在Rule,我們可能有:

import importlib 

class Rule(): 
    """A template class that all rules inherit from and are instantiated from.""" 

    def __init__(self, rule): 
     # load the rule by name from rule definitions 
     try: 
      self.Rule = importlib.import_module('defs._'+ rule) 
     except ImportError: 
      print 'Failed to find rule definiton while attempting to load 


    #other generic functions to inherit below 

這是最乾淨的方式是什麼?我不確定這是否是標準做法。

回答

1

這裏有幾個問題。讓我做一個接一個:

  • 你打算什麼並不真正需要_discardRule繼承。你正在使用繼承和組合,這看起來很混亂。

  • 您返回的規則仍具有Rule類型,而不是_discard。也許這就是你想要的,也許不是...

  • Rule('discard')不能靜態檢查,並且不會得到你期望的自動完成(如果你使用的是IDE)。

這裏有一些想法改進:

  • 純的組合:保留當前的初始化,但不要從Rule繼承。爲通用功能使用另一個類,或將父項傳遞給_discard構造函數。 (第二個會產生雖然參考環)

與其他類的通用功能它可以是這樣的:

class RuleTrait(object): 
    def some_common_stuff(self): 
     ... 

class _discard(RuleTrait): 
    def do_work(self): 
     some_common_stuff() 

class Rule(object): 
    def __init__(self, typ): 
     self.impl = _get_impl_by_name(typ) 

    def __getattr__(self, name): 
     return getattr(self.impl, name) 

Rule("discard").do_work() # this will be forwarded to _discard.do_work 
  • 實際繼承:不要使用普通的構造,但直接上課。 Rule('discard')並不比rules.Discard()差,它會給你更好的類型檢查。你可以擺脫進口魔法。

  • 如果您在某些情況下需要更多進口魔法,請將其改爲工廠。 Rule(...)只能創建Rule對象。但是你可以寫一個make_rule('discard')來代替你需要的任何實現。

+0

是的,爲了清晰起見,我希望每個規則的類型都是'Rule',而不是'_discard'。但是關於使用另一個類來實現泛型功能的第一個解決方案的問題,這將如何工作?假設我有'RuleTemplate'類,其中'_discard'和所有其他創建的規則繼承自。如果我創建了一個規則,例如:'r = Rule('discard')' - 我不能執行像'Rule.execute(args)'或'Rule.getName()'這樣的通用函數。 – X33

+1

@ X33我添加了一個樣本。您可以將所有未知屬性轉發給實際實現。儘管你的類具有通用規則特徵,但並不需要公開。 – viraptor

+0

好的,我現在明白了。我非常感謝澄清。這可能是針對我的情況的最佳方法。如果你有時間,我還有一個最後的問題:關於工廠方法,這個解決方案與工廠不是很相似嗎? – X33

1

你在做什麼看起來類似於動態加載數據庫遷移。 Django和類似的數據庫相關的項目可能有代碼,你可以看看。

我寫了一些自動加載和導入的代碼。 看那load_migrations功能我寫到這裏https://github.com/someones/exodus/blob/master/exodus/init.py

  1. 核心出埃及記類負載遷移從一個指定的目錄。

  2. 每個文件都有一個擴展BaseMigration對象的類。

  3. BaseMigration的元類將在解析時註冊一箇中心的遷移列表。