Помимо слияния файлов, существует несколько опций, которые, как вы сказали, не одобряет ваша конвенция на рабочем месте. (Варианты, приведенные ниже, адаптированы для Python 3 относительно ответа, связанного в этом комментарии от Sanyash . Я подумал, что имеет смысл включить сюда ответ, поскольку этот вопрос не касается непосредственно относительного импорта.)
Переместить циклический импорт в конец своих файлов
Файл a.py
становится:
from .abstract import Abstract
class A(Abstract):
# ...
from .b import B
и b.py
изменяются одинаково. Это простое изменение, но имеет тот недостаток, что ваш импорт разбросан. Кто-то может «очистить» ваш код, переместив импорт в начало, и столкнуться с той же путаницей, что и у вас. (Вы можете оставить комментарий, но люди часто пропускают комментарии.)
Импорт модулей вместо классов
Вы также можете сделать так, чтобы каждый модуль импортировал другой модуль, а не импортировал из него. a.py
становится:
from .abstract import Abstract
from . import b
class A(Abstract):
# ...
def as_b(self):
return b.B(int(self.string)) # note the change to use b.B
и, конечно, b.py
изменяется аналогично. Это кажется мне самым чистым решением - я настоятельно предпочитаю сохранять импорт вместе, когда это возможно. (Я не могу думать о каких-либо недостатках этого подхода, но если кто-то знает о них, пожалуйста, оставьте комментарий, и я обновлю его.)
Переместить импорт туда, где он используется
Если вы ссылаетесь только на B
из a.py
в одном месте, как это, вы можете переместить импорт в функцию, где это необходимо:
from .abstract import Abstract
class A(Abstract):
# ...
def as_b(self):
from .b import B
return B(int(self.string))
и то же самое для b.py
. Это имеет преимущество перед первым вариантом: легче понять, почему импорт не на вершине, и я чувствую, что это менее вероятно приведет к путанице или ошибкам в будущем. Однако он может маскировать ошибки импорта, поэтому я не думаю, что он идеален. Это также немного замедлит первый вызов as_a
и as_b
, поскольку импорт будет происходить при первом вызове каждой функции и займет ненулевое время.