2011-09-01 22 views
4

我具有從不同的數據庫類型的負載數據(源碼,MySQL的等)的模塊包含一類db_loader和亞類(sqlite_loader,mysql_loader),其從繼承的模塊(db.py)它。挑基於參數的子類

正在使用的類型的數據庫是在一個單獨的文件PARAMS,

用戶如何得到正確的對象回來?

即我該怎麼辦:

loader = db.loader()

難道我使用一個名爲裝載機db.py模塊的方法還是有更優雅的方式,其中一類可以選擇根據自己的子類參數?有沒有一種標準的方法來做這種事情?

回答

4

聽起來像是你想要的Factory Pattern。你定義一個工廠方法(或者您的模塊中,或者在它能夠產生的所有對象共同的父類),您傳遞參數,它將返回正確的類的實例。在python中,這個問題比維基百科文章中的一些細節更簡單一些,因爲你的類型是動態的。

class Animal(object): 

    @staticmethod 
    def get_animal_which_makes_noise(noise): 
     if noise == 'meow': 
      return Cat() 
     elif noise == 'woof': 
      return Dog() 

class Cat(Animal): 
    ... 

class Dog(Animal): 
    ... 
+0

謝謝!這似乎是最優雅的解決方案! –

+2

是啊,但是這將需要我每次我有一個新的動物的時間延長了工廠方法..任何方式很好地「自動檢測」的子類,其中'noise'是子類裏面的一些屬性值? –

2

我會存儲在PARAMS文件中的子類的名稱,並有一個工廠方法,將實例化的類它的名字:

class loader(object): 
    @staticmethod 
    def get_loader(name): 
    return globals()[name]() 

class sqlite_loader(loader): pass 

class mysql_loader(loader): pass 

print type(loader.get_loader('sqlite_loader')) 
print type(loader.get_loader('mysql_loader')) 
+0

謝謝!這似乎是一個很好的解決方案,我認爲基本上與actionshrimp相同? –

+1

@Mike城:從actionshrimp的解決方案的主要區別是,在這裏你不需要明確地命名每個類的一系列'if'-'elif'語句。換句話說,如果你添加一個新的loader類,它可以立即在params文件中指定:不需要記住進入並更新那個大的if語句! – NPE

1

商店在dict類,實例正確的一個根據您的PARAM:

db_loaders = dict(sqlite=sqlite_loader, mysql=mysql_loader) 
loader = db_loaders.get(db_type, default_loader)() 

其中db_type是要切換的參數,則和sqlite_loadermysql_loader是「加載器」類。