Модуль Python, общий для нескольких продуктов - PullRequest
1 голос
/ 13 мая 2010

Я работаю над классом python, который используется двумя продуктами. 90% функциональности относится к обоим продуктам. Для 10%, которые отличаются, код напичкан такими вещами:

#Start of file
project = 'B'

#Some line of code

if project == 'A':
    import moduleA
elif project == 'B':
    import moduleB

#Many lines of code

if project == 'A':
    print moduleA.doA(2)
elif project == 'B':
    print moduleB.doB(2)

Это выглядит не очень элегантно и не очень читабельно, кто-нибудь сталкивался с подобными вещами раньше? Есть ли лучшие способы сделать это?

Ответы [ 3 ]

3 голосов
/ 13 мая 2010

Нет, так как это очень плохой дизайн. Если на поведение вашего модуля влияет проект, в котором он используется, он должен принять объект, функцию или другой обратный вызов для поведения, специфичного для проекта. Мое предложение состоит в том, чтобы отделить части, которые являются общими, и превратить их в единый модуль, а для всего, что связано с проектом, добавить зависимость от объекта, который необходимо передать, и потребовать, чтобы объект соответствовал некоторому интерфейсу , Затем оберните поведение, характерное для вашего проекта, в объект, соответствующий требуемому интерфейсу, и передайте его общему общему модулю.

0 голосов
/ 13 мая 2010

Другой возможный подход, если ни один из двух приведенных ответов не является практичным, заключается в определении интерфейса на уровне импорта. Например:

if project == 'A':
  from moduleA import doA as doproject
elif project == 'B':
  from moduleB import doB as doproject

# many lines of code

doproject(2)

Эта концепция (хотя и не эта конкретная проблема) является одной из тех вещей, для которых "импорт X как Y" действительно полезен.

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

0 голосов
/ 13 мая 2010

Ваш совместно используемый модуль должен реализовать базовый класс с функциональностью, общей для обоих использующих модулей, тогда каждый использующий модуль будет создавать подкласс этого базового класса и добавлять или изменять то, что необходимо. Существуют и другие хорошие подходы (например, предложение в ответе @ Michael, известное как шаблоны проектирования Dependency Injection), но обычно создание подклассов и переопределений - это самый простой способ «настроить» функциональность для различных конкретных потребностей (это приводит к высоким и жесткое соединение, но это часто вполне приемлемо в качестве стоимости простоты).

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