Шаблоны проектирования Python, кросс-импорт - PullRequest
1 голос
/ 26 августа 2009

Я использую Python для автоматизации сложной процедуры, которая имеет несколько вариантов. Я хочу иметь следующую структуру в Python. - Один «класс потока», содержащий поток - Один вспомогательный класс, который содержит много «черных ящиков» (функции, которые не часто меняются).

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

В классе потока у меня есть глобальная переменная, которую я хочу, чтобы пользователь принудительно вводил при каждом запуске. Линия выглядит следующим образом. print («Хотели бы вы увидеть отладочный вывод (enter = no)?») debug = getUserInput ()

Функция getUserInput () должна быть расположена во вспомогательном классе, поскольку она никогда не изменяется. Для getUserInput нужна глобальная переменная из класса потока, которая указывает, должен ли пользовательский ввод соответствовать командной строке Linux или Eclipse (работает в Windows).

Мой вопрос: как я могу структурировать это наилучшим образом? В настоящее время это выглядит следующим образом: Поток-класс:

import helper_class

isLinux = 1

debug = getUserInput()

Хелпер-класс:

import os, flow_class

def getUserInput():
    userInput = input ()
    if (flow_class.isLinux == 1):
        userInput = userInput[:-1]
    return userInput

В настоящее время это дает мне следующую ошибку из-за перекрестного импорта:

Traceback (most recent call last):
  File "flow_class.py", line 1, in <module>
    import helper_class
  File "helper_class.py", line 1, in <module>
    import os, flow_class
  File "flow_class.py", line 5, in <module>
    debug = getUserInput()
NameError: name 'getUserInput' is not defined

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

Ответы [ 3 ]

2 голосов
/ 26 августа 2009

вам нужно сделать helper_class.getUserIinput() в вашем flow_class. Дело не в перекрестном импорте. После исправления вы получите AttributeError, что действительно связано с перекрестным импортом.

На этом этапе вам необходимо реализовать логику получения getUserInput, определенную перед импортом flow_class.

И прокомментируйте ваше последнее утверждение: ваше предположение неверно. Код будет намного понятнее, если вы будете использовать явные локальные значения.

1 голос
/ 26 августа 2009

Я хотел бы спросить вас о вашем последнем предложении.

Обычно, как также указано в CC2 , использование глобальных переменных помогает при написании кода, но не при его чтении.
И код читается намного больше, чем написано; я понимаю, что в вашем случае вы снова и снова изменяете один и тот же сценарий.

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

Как сказано в дзен Python, явное лучше, чем неявное .

1 голос
/ 26 августа 2009

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

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

попробуйте что-то вроде:

debug = getUserInput(isLinux=True)

Вот еще несколько предложений

  • Вы упоминаете, что есть много параметров, которые вы будете часто менять. Должны ли они быть жестко закодированы? Попробуйте использовать файл конфигурации или передать dict () из функции flow в качестве параметра. Таким образом, у вас есть центральное место для изменения общих переменных без необходимости погружаться!
  • ваш класс 'flow / helper' звучит как парадигма Controller / Model . Это хорошо. Но ваша модель не должна импортировать ваш контроллер.

Это не предложения, относящиеся к «питоническому стилю», это общие практики программирования. Если вы беспокоитесь о разработке программ, попробуйте прочитать Pragmatic Programmer , у них есть отличные советы для рабочего процесса и дизайна. Также есть Код Завершен , который предложил Роберто.

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