Как вы могли бы поменять конкретную реализацию базы данных в Python? - PullRequest
1 голос
/ 07 сентября 2010

Если у меня есть отдельный класс для моих вызовов базы данных, и я создаю другую реализацию уровня базы данных, но, скажем, с другим хранилищем данных.

Есть ли способ для меня полностью поменять реализацию без необходимости изменения кода?

т.е. Я начинаю проект, поэтому могу правильно спроектировать вещи, чтобы добиться этого с самого начала.

Примечание. Я буду использовать этот шаблон и для других частей сайта, а не только для слоя db, поэтому он не является специфичным только для слоя db.

1 Ответ

2 голосов
/ 07 сентября 2010

Пока два модуля реализуют один и тот же интерфейс (классы с одинаковыми именами, методами и другими атрибутами, функции с одинаковыми именами и сигнатурами, ...), вы можете выбрать один или другой в то время, когда ваше приложение запускается, например, на основе некоторого файла конфигурации, и импортирует выбранный файл с фиксированным именем. Все остальное ваше приложение может затем использовать это фиксированное имя и, за исключением кода запуска, быть в блаженном неведении о любых махинациях, которые могли быть сделаны в начале.

Например, рассмотрим упрощенный случай:

# 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!'. * 1010. *

Конечно, в реальной жизни у вас будет несколько модулей, каждый с несколькими функциями, классами и так далее, но общие принципы остаются очень схожими. Просто будьте особенно внимательны с модулями с квалифицированными именами (такими как foo.bar), т. Е. С модулями, которые должны находиться в пакете (в данном случае foo). Для них вы не можете просто использовать возвращаемое значение __import__, но должны использовать немного более обходной подход, такой как:

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

, то есть игнорировать возвращаемое значение __import__ и достичь правого значения для левого значения (с фактическим именем в качестве ключа) в словаре sys.modules - , что является модулем объект, который вы ищете, и который вы можете установить обратно в sys.modules с «поддельным именем», с помощью которого все остальные приложения смогут в любой момент безупречно импортировать его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...