Избегание циклического (циклического) импорта в Python?

Один из способов – использовать import x, не используя ключевое слово «from». Итак, вы все время ссылаетесь на вещи с их пространством имен.

Есть ли другой путь? как делать что-то вроде C ++ ifnotdef __b__ def __b__ типа вещи?

3 Solutions collect form web for “Избегание циклического (циклического) импорта в Python?”

Объедините любые пары модулей, которые зависят друг от друга в одном модуле. Затем введите дополнительные модули, чтобы вернуть старые имена.

Например,

 # a.py from b import B class A: whatever # b.py from a import A class B: whatever 

становится

 # common.py class A: whatever class B: whatever # a.py from common import A # b.py from common import B 

Циркулярный импорт является «запахом кода» и часто (но не всегда) указывает на то, что некоторые рефакторинги будут уместны. Например, если Ax использует By и By использует Az , то вы можете подумать о перемещении Az в свой собственный модуль.

Если вы считаете, что вам нужен круговой импорт, я бы рекомендовал импортировать модуль и ссылаться на объекты с полностью квалифицированными именами (т. import A и использовать Ax а не from A import x ).

Если вы пытаетесь сделать from A import * , ответ прост: не делайте этого. Обычно вы должны делать import A и ссылаться на квалифицированные имена.

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

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

На самом деле, мне трудно представить, какой случай, когда import * оправдан, и круговые зависимости даже возможны.

Если вы делаете from A import foo , есть способы обойти это (например, import A then foo = A.foo ). Но вы, вероятно, не хотите этого делать. Опять же, подумайте, действительно ли вам нужно привносить foo в свои имена, имена которых являются именами, – это функция, а не проблема.

Если вы делаете from A import foo только для удобства реализации своих функций, потому что A на самом деле long_package_name.really_long_module_name и ваш код нечитабелен из-за всех этих вызовов long_package_name.really_long_module_name.long_class_name.class_method_that_puts_me_over_80_characters , помните, что вы всегда можете import long_package_name.really_long_module_name as P а затем используйте P для квалифицированных вызовов.

(Кроме того, помните, что с любым from выполненных для удобства реализации вы, вероятно, захотите указать __all__ чтобы убедиться, что импортированные имена не являются частью вашего пространства имен, если кто-то делает import * на вас из интерактивного сессия.)

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

  • kivy: ImportError: Нет модуля с именем app
  • AttributeError (объект '' str 'не имеет атрибута' read '')
  • Как получить текущее время в python и разбить на год, месяц, день, час, минуту?
  • BeautifulSoup - Получить текст в теге только в том случае, если определенная строка найдена
  • python reg ex включить отсутствующие запятые
  • стили строки ошибок openpyxl
  • Функция символа Python, где находится «Z»?
  • Subclassing matplotlib Текст: манипулировать свойствами дочернего исполнителя
  •  
    Interesting Posts for Van-Lav

    развязанный интерфейс и бэкэнд с Django, webpack, reactjs, agent-router

    Такая же производительность у разных работников в многопроцессорной обработке

    matplotlib bar graph black – как удалить границы бара

    Сортировка по дате с помощью DB в Django

    параллельные испытания pytest

    NLTK не смог найти stanford-postagger.jar! Установите переменную среды CLASSPATH

    Python 3: ImportError «Нет модуля с именем Setuptools»

    Как запустить собственный фиксатор 2to3?

    Ошибка Rpy2 wac-a-mole: R_USER не определен

    Pymongo или Mongodb обрабатывает два равных словаря python как разные объекты. Могу ли я заставить их лечиться одинаково?

    Получить флаги TCP с помощью Scapy

    Python: TypeError: индексы списка должны быть целыми числами, а не списком

    Как вы можете защитить себя от звонка из библиотеки, который может вешать бесконечно?

    Автоматическое создание альфа-числового идентификатора для модели Django

    Django IntegerField с параметрами выбора (как создать 0-10 целых параметров)

    Python - лучший язык программирования в мире.