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 classEnt: ...
physics.py:
from entity import Ent classPhysics: ...
Затем я запускаю из 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 - но как я могу обойти проблему?
У вас циклический зависимый импорт. physics.py импортируется из entity до определения класса Ent и physics пытается импортировать entity то, что уже инициализируется. Удалите зависимость от модуля physics from entity.
Ответ 2
Хотя вам определенно следует избегать циклических зависимостей, вы можете отложить импорт в python.
например:
import SomeModule
defsomeFunction(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 classcls: def__init__(self): self.y = x.y
Поскольку вы больше не ссылаетесь на содержимое модуля на верхнем уровне, python может скомпилировать модуль без фактического доступа к содержимому циклической зависимости. Под верхним уровнем я подразумеваю строки, которые будут выполняться во время компиляции, в отличие от содержимого функций (например. y = x.y). Статические переменные или переменные класса, обращающиеся к содержимому модуля, также вызовут проблемы.
Ответ 4
В моем случае я работал в записной книжке Jupyter, и это происходило из-за того, что импорт уже кэшировался с того момента, когда я определил класс / функцию внутри моего рабочего файла.
Я перезапустил свое ядро Jupyter, и ошибка исчезла.