Вопрос по python, python-2.7 – Избегать циклического (циклического) импорта в Python?

7

Одним из способов является использование импорта х, без использования "от" ключевое слово. Итак, вы ссылаетесь на вещи с их пространством имен везде.

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

@alinsoar It 'не является точной копией - этот вопрос задал вопрос, что происходит при круговом импорте; и этот вопрос требует методов, чтобы избежать их. Edward Loper
Речь идет о двух модулях, которые импортируют друг друга, то есть циклически. Я не смотрел, если решение. Проблема та же. alinsoar
Кроме того, если выпытаясь сделать это, чтобы иметь возможность печататьf вместоx.f, Зачем? Это только потому, чтоx на самом деле это имя вложенного модуля длиной 40 символов, или потому что вы хотите, чтобы Python больше походил на другой язык, или по какой-то реальной причине (например, вы хотитеtry вfrom json import loads и определить местныйloads если не получится)? abarnert
Этот пост является дубликатом:stackoverflow.com/questions/744373/... alinsoar

Ваш Ответ

3   ответа
10

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

Например.,

# 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
@jdi: да. Спасибо, исправили это. Fred Foo
Это заставляет начать объявлять все вcommon.py скорее, чемa.py а такжеb.py, Не хорошее решение ИМХО. Nick
Я думаю, что вы хотели сделатьfrom common import A а также ?from common import B jdi
0

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

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

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

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

Если ты'делаешьfrom A import fooЕсть способы обойти это (например,import A затем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

5

Круговой импорт является "кодовый запах " и часто (но не всегда) указывают, что какой-то рефакторинг будет уместным. Например, еслиA.x использованияB.y а такжеB.y использованияA.zтогда вы можете рассмотреть возможность переездаA.z в свой собственный модуль.

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

Что если кто-то делает явную проверку типов? Я пытаюсь сделать это прямо сейчас, чтобы я мог предоставить очень подробное сообщение об ошибке, а не какой-то запутанный след, который мои клиенты не делаютТ понять. Nick

Похожие вопросы