Как избежать циклических зависимостей в модуле проверки

Недавно я провел рефакторинг своего кода, чтобы поместить методы проверки ввода, общие для нескольких классов, в их собственный модуль validate.py. Некоторые из этих методов проверки проверяют, являются ли их входные данные экземпляром класса, например, MyClass. Поэтому validate.py должен импортировать MyClass, чтобы его метод is_MyClass мог проверить, isinstance(input, MyClass). Но я хочу использовать некоторые методы проверки из validate.py в MyClass для очистки ввода в MyClass.my_method, поэтому MyClass должен импортировать validate.py.

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

Но повторное использование кода — хорошая идея. Итак, как лучше всего делиться методами проверки таким образом?


person Will    schedule 11.04.2014    source источник


Ответы (2)


Я думаю, что части кода проверки, относящиеся к одному из классов, вероятно, следует поместить в сам класс - может быть, как метод класса? Таким образом, «общий» код проверки может просто вызвать obj.validate() в нужное время. Тогда вам не нужно импортировать классы из общего кода проверки.

person Tom Dalton    schedule 12.04.2014
comment
Да, это то, что я понял. Подумал, что может быть какой-нибудь крутой супер-питоновский способ сделать это. Спасибо! - person Will; 12.04.2014

Хотя ответ Тома Далтона, вероятно, верен с точки зрения наилучшего дизайна, возможно, стоит отметить, что циклы импорта часто отлично работают в Python.

Однако ограничение заключается в том, что вам необходимо использовать синтаксис import my_module и избегать кода верхнего уровня (глобального), использующего импортированные модули. Объявление функций (или классов с методами), использующих импортированный модуль, допустимо.

Обычно у вас возникают проблемы, если вы используете from my_module import obj или что-то подобное, так как это будет работать только в том случае, если obj уже был определен в другом модуле. Если этот другой модуль находится в процессе импорта вашего модуля, возможно, определение класса или присвоение глобальной переменной еще не произошло.

Таким образом, для вашего конкретного случая альтернативным решением может быть использование validate модуля import my_class, тогда is_MyClass может выполнять isinstance(input, my_class.MyClass).

person Blckknght    schedule 12.04.2014