Загружать разные модули без изменения логического файла
Предположим, у меня есть 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 raw python-коды, но, похоже, не очень хорошее решение. Или если я могу сделать единую обертку в
sns_api/__init__.py
Кто-нибудь может помочь?
3 ответа
С двумя я бы сделал
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')
, но вам, вероятно, это не нужно.
Имейте функцию "фабрики" в каждом модуле, делайте динамический импорт и вызывайте фабрику для загруженного модуля. По крайней мере, это один из способов сделать это. Помните, что питонский способ - это "типизирование утки", поэтому фабрика возвращает объект, а клиент использует его через "утиные вызовы":-)
Вы также можете использовать exec:
exec "from sns_api.%s import 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