ImportError: Невозможно импортировать имя X - PullRequest
418 голосов
/ 13 февраля 2012

У меня есть четыре разных имени файла: главный, векторный, объект и физика. Я не буду публиковать весь код, только импорт, потому что я думаю, что здесь ошибка. (Если хотите, могу выложить больше)

Main:

import time
from entity import Ent
from vector import Vect
#the rest just creates an entity and prints the result of movement

Организация:

from vector import Vect
from physics import Physics
class Ent:
    #holds vector information and id
def tick(self, dt):
    #this is where physics changes the velocity and position vectors

Vector:

from math import *
class Vect:
    #holds i, j, k, and does vector math

Физика:

from entity import Ent
class Physics:
    #physics class gets an entity and does physics calculations on it.

Затем я запускаю файл 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

Я очень плохо знаком с Python, но долгое время работал с C ++. Я предполагаю, что ошибка происходит из-за импорта сущности дважды, один раз в основную, а затем в физике, но я не знаю обходного пути. Кто-нибудь может помочь?

Ответы [ 8 ]

419 голосов
/ 13 февраля 2012

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

119 голосов
/ 28 августа 2013

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

например:

import SomeModule

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

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

98 голосов
/ 23 мая 2014

Это круговая зависимость. Это может быть решено без каких-либо структурных изменений в коде. Проблема возникает из-за того, что в vector вы требуете, чтобы entity был сделан доступным для использования немедленно, и наоборот. Причиной этой проблемы является то, что вы запрашиваете доступ к содержимому модуля до его готовности - с помощью from x import y. По сути это то же самое, что и

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). Статические или классовые переменные, обращающиеся к содержимому модуля, также вызовут проблемы.

17 голосов
/ 20 ноября 2017

Очень важно прояснить логику.Эта проблема возникает из-за того, что ссылка становится мертвым циклом.

Если вы не хотите изменять логику, вы можете поместить оператор импорта, вызвавший ImportError, в другую позицию файла, дляпример конец.

a.py

from test.b import b2

def a1():
    print('a1')
    b2()

b.py

from test.a import a1

def b1():
    print('b1')
    a1()

def b2():
    print('b2')

if __name__ == '__main__':
    b1()

Вы получите ошибку импорта: ImportError: cannot import name 'a1'

Но если мы изменим позицию из test.b import b2 в A, как показано ниже:

a.py

def a1():
    print('a1')
    b2()

from test.b import b2

И мы можем получить то, что хотим:

b1
a1
b2
13 голосов
/ 07 апреля 2017

Я тоже получил эту ошибку, по другой причине ...

from my_sub_module import my_function

Основной сценарий имел окончания строк в Windows.my_sub_module имел окончание строки UNIX.Изменение их на одно и то же решило проблему.Они также должны иметь одинаковую кодировку символов.

4 голосов
/ 03 мая 2019

Это круговая зависимость. мы можем решить эту проблему, используя import модуль или класс или функцию там, где нам нужно. если мы используем этот подход, мы можем исправить круговую зависимость

A.py

from B import b2
def a1():
    print('a1')
    b2()

B.py

def b1():
   from A import a1
   print('b1')
   a1()

def b2():
   print('b2')
if __name__ == '__main__':
   b1() 
4 голосов
/ 18 октября 2018

Не называйте свой текущий скрипт Python именем какого-либо другого импортируемого вами модуля

Решение: переименуйте ваш рабочий скрипт Python

Пример:

  1. вы работаете в medicaltorch.py
  2. в этом сценарии, у вас есть: from medicaltorch import datasets as mt_datasets где medicaltorch должен быть установленный модуль

Этопотерпит неудачу с ImportError.Просто переименуйте ваш рабочий скрипт на Python в 1.

3 голосов
/ 19 октября 2018

Пока не видите этого - это невероятно глупо, но убедитесь, что вы импортируете правильную переменную / функцию.

Я получил эту ошибку

ImportError: невозможно импортировать имя IMPLICIT_WAIT

, поскольку моя переменная была IMPLICIT_TIMEOUT.

, когда я изменил свой импорт на использование правильного имени, ошибка больше не возникает️

...