你怎么能在python中换掉特定的数据库实现?

时间:2010-09-06 23:40:19

标签: python ioc-container

如果我的db调用有一个单独的类,我创建了db层的另一个实现,但是说有不同的数据存储。

有没有办法让我可以完全交换实现而无需更改分配代码?

即。我正在开始一个项目,所以我可以从一开始就正确地设计一些东西。

注意:我也会将此模式用于站点的其他部分,而不仅仅是db层,因此它不仅仅是db层的特定。

1 个答案:

答案 0 :(得分:2)

只要两个模块实现完全相同的接口(具有相同名称,方法和其他属性的类,具有相同名称和签名的函数,......),您可以在应用程序时选择一个或另一个例如,在某些配置文件的基础上启动,并以固定名称导入所选的一个。然后,您的所有其他应用程序都可以使用该固定名称,并且在启动代码的基础上,幸运地不知道可能在开始时已经完成的任何恶作剧。

例如,考虑一个简化的案例:

# english.py
def greet(): return 'Hello!'

# italian.py
def greet(): return 'Ciao!'

# french.py
def greet(): return 'Salut!'

# config.py
langname = 'italian'

# startit.py
import config
import sys
lang = __import__(config.langname)
sys.modules['lang'] = lang

现在,应用程序的所有其余部分只能import lang,并且它将以italian模块的名称获得,因此,在调用lang.greet()时,它将获得字符串'Ciao!'

当然,在现实生活中,你将拥有多个模块,每个模块都有多个功能,类和诸如此类的东西,但一般原则保持非常相似。只需要特别注意具有限定名称的模块(例如foo.bar),即必须驻留在包中的模块(在本例中为foo)。对于那些,你不能只使用__import__的返回值,但必须使用稍微更迂回的方法,例如:

import sys
def importanyasname(actualname, fakename):
    __import__(actualname)
    sys.modules[fakename] = sys.modules[actualname]

也就是说,忽略__import__的返回值,并在sys.modules字典 - 那个 中找到左边的值(实际名称作为键) strong>是您寻找的模块对象,并且您可以使用“假名称”重新设置为sys.modules,通过该名称,应用程序的所有其余部分将能够随时幸福地导入它。