2011-09-01 46 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是“加载器”类。