假设我有2个不同的模块,它们具有统一(相同)的接口。文件列表如下:
root/
logic.py
sns_api/
__init__.py
facebook/
pyfacebook.py
__init__.py
myspace/
pymyspace.py
__init__.py
pyfacebook.py和pymyspace.py具有相同的接口,这意味着:
# in pyfacebook.py
class Facebook:
def __init__(self, a, b):
# do the init
def method1(self, a, b, ...):
# do the logic
# in pymyspace.py
class Myspace:
def __init__(self, a, b):
# do the init
def method1(self, a, b, ...):
# do the logic
现在我有一个问题。我想在logic.py中执行逻辑而不复制代码,所以我想知道如何设置一个标志来显示我使用的模块,python将自动加载正确的代码,这意味着:
# in logic.py
PLATFORM = "facebook"
# import the right modules in, complete the logic with the current platform
# create the right instance and invoke the right methods
然后我改变PLATFORM ='myspace',逻辑将自动运行。
那我怎么能这样做呢?
我想知道使用动态导入是否可行,或者eval原始python代码,但似乎不是一个好的解决方案。或者,如果我可以在
中制作统一的包装器sns_api/__init__.py
任何人都可以提供帮助吗?
答案 0 :(得分:6)
只有两个我会做
if platform == 'facebook':
from pyfacebook import FaceBook as Platform
elif platform == 'myspace':
from pymyspace import Myspace as Platform
else:
raise RuntimeError, "not a valid platform"
并在其余代码中使用Platform
。它在库中就像这样完成,请参阅os
模块。
您可以使用name =
__import__
('module')
进行真正的动态导入,但您可能不需要这样做。
答案 1 :(得分:0)
在每个模块中都有一个“工厂”功能,进行动态导入并为加载的模块调用工厂。至少,这是一种方法。请记住,pythonic方式是“duck typing”,以便工厂返回一个对象,客户端通过“duck calls”使用它: - )
答案 2 :(得分:0)
您也可以使用exec:
exec "from sns_api.%s import Platform" % PLATFORM
然后在您的实现文件中,为Platform分配一些内容:
# in pyfacebook.py
class Facebook:
def __init__(self, a, b):
# do the init
def method1(self, a, b, ...):
# do the logic
Platform = Facebook