Вопрос-Ответ

What can I do about "ImportError: Cannot import name X" or "AttributeError: ... (most likely due to a circular import)"?

Что я могу сделать с "ImportError: не удается импортировать имя X" или "AttributeError: ... (скорее всего, из-за циклического импорта)"?

У меня есть некоторый код, разбросанный по нескольким файлам, которые пытаются import отделить друг от друга, следующим образом:

main.py:

from entity import Ent

entity.py:

from physics import Physics
class Ent:
...

physics.py:

from entity import Ent
class Physics:
...

Затем я запускаю из main.py и получаю следующую ошибку:

Traceback (most recent call last):
File "main.py", line 2, in <module>
from entity import Ent
File ".../entity.py", line 5, in <module>
from physics import Physics
File ".../physics.py", line 2, in <module>
from entity import Ent
ImportError: cannot import name Ent

Я предполагаю, что ошибка связана с импортом entity дважды - один раз в main.py и позже в physics.py - но как я могу обойти проблему?


Смотрите также Что происходит при использовании взаимного или циклического импорта в Python? для получения общего обзора того, что разрешено и что вызывает проблему при циклическом импорте. См. Почему циклический импорт, по-видимому, работает дальше в стеке вызовов, но затем вызывает ImportError еще ниже? для получения технических подробностей о почему и как возникает проблема.

Переведено автоматически
Ответ 1

У вас циклический зависимый импорт. physics.py импортируется из entity до определения класса Ent и physics пытается импортировать entity то, что уже инициализируется. Удалите зависимость от модуля physics from entity.

Ответ 2

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

например:

import SomeModule

def someFunction(arg):
from some.dependency import DependentClass

это (по крайней мере, в некоторых случаях) позволит обойти ошибку.

Ответ 3

This is a circular dependency. It can be solved without any structural modifications to the code. The problem occurs because in vector you demand that entity be made available for use immediately, and vice versa. The reason for this problem is that you asking to access the contents of the module before it is ready -- by using from x import y. This is essentially the same as

import x
y = x.y
del x

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

a = module() # import a

# rest of module

a.update_contents(real_a)

Чтобы python мог работать с циклическими зависимостями, вы должны использовать import x только стиль.

import x
class cls:
def __init__(self):
self.y = x.y

Поскольку вы больше не ссылаетесь на содержимое модуля на верхнем уровне, python может скомпилировать модуль без фактического доступа к содержимому циклической зависимости. Под верхним уровнем я подразумеваю строки, которые будут выполняться во время компиляции, в отличие от содержимого функций (например. y = x.y). Статические переменные или переменные класса, обращающиеся к содержимому модуля, также вызовут проблемы.

Ответ 4

В моем случае я работал в записной книжке Jupyter, и это происходило из-за того, что импорт уже кэшировался с того момента, когда я определил класс / функцию внутри моего рабочего файла.

Я перезапустил свое ядро Jupyter, и ошибка исчезла.

python