main, vector, entity 및 physics라는 네 가지 파일이 있습니다. 오류가있는 곳이라고 생각하기 때문에 모든 코드를 게시하지 않고 가져 오기 만합니다. (원한다면 더 게시 할 수 있습니다)
본관:
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
벡터:
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 ++로 작업했습니다. 나는 오류가 엔티티에서 두 번, 메인에서 한 번, 나중에 물리에서 가져 오기 때문이라고 생각하지만 해결 방법을 모르겠습니다. 누구든지 도울 수 있습니까?
답변
순환 종속 가져 오기가 있습니다. physics.py
에서 수입되는 entity
클래스가 이전에 Ent
정의 및 physics
수입에 대한 시도가 entity
이미 초기화된다. 모듈 physics
에서에 대한 종속성을 제거하십시오 entity
.
답변
순환 의존성을 피해야하지만 파이썬에서 가져 오기를 연기 할 수 있습니다.
예를 들면 다음과 같습니다.
import SomeModule
def someFunction(arg):
from some.dependency import DependentClass
이것은 (적어도 일부 경우) 오류를 피할 것입니다.
답변
이것은 순환 종속성입니다. 코드를 구조적으로 수정하지 않고도 해결할 수 있습니다. 에 있기 때문에 문제가 발생합니다 vector
당신이 요구하는 그 entity
반대의 즉시 사용 가능하게하고, 그 반대도 될 수있다. 이 문제의 원인은 준비하기 전에 모듈의 내용에 액세스하도록 요청하기 때문입니다 from x import y
. 이것은 본질적으로
import x
y = x.y
del x
파이썬은 순환 의존성을 감지하고 무한한 수입 루프를 방지 할 수 있습니다. 본질적으로 일어나는 일은 모듈에 대해 빈 자리 표시자가 만들어지는 것입니다 (즉, 내용이 없음). 순환 종속 모듈이 컴파일되면 가져온 모듈을 업데이트합니다. 이것은 이런 식으로 작동합니다.
a = module() # import a
# rest of module
a.update_contents(real_a)
파이썬이 순환 종속성으로 작업 할 수 있으려면 import x
스타일 만 사용해야 합니다.
import x
class cls:
def __init__(self):
self.y = x.y
더 이상 최상위 레벨에서 모듈의 내용을 참조하지 않기 때문에 Python은 실제로 순환 종속성의 내용에 액세스하지 않고도 모듈을 컴파일 할 수 있습니다. 최상위 레벨은 함수의 내용 (예 :)과 반대로 컴파일 중에 실행될 라인을 의미합니다 y = x.y
. 모듈 내용에 액세스하는 정적 또는 클래스 변수도 문제를 일으킬 수 있습니다.
답변
논리를 명확하게하는 것이 매우 중요합니다. 참조가 데드 루프가되기 때문에이 문제가 나타납니다.
논리를 변경하지 않으려면 ImportError를 일으킨 import 문을 파일의 다른 위치 (예 : 끝)에 넣을 수 있습니다.
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'
그러나 다음과 같이 A에서 test.b import b2의 위치를 변경하면 :
a.py
def a1():
print('a1')
b2()
from test.b import b2
그리고 우리는 우리가 원하는 것을 얻을 수 있습니다 :
b1
a1
b2
답변
이것은 순환 종속성입니다. 가져 오기 모듈이나 필요한 클래스 또는 함수 를 사용하여이 문제를 해결할 수 있습니다 . 이 방법을 사용하면 순환 종속성을 수정할 수 있습니다
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()
답변
다른 이유로이 오류가 발생했습니다 …
from my_sub_module import my_function
기본 스크립트에는 Windows 줄 끝이있었습니다. my_sub_module
유닉스 줄 끝이 있었다. 그것들을 동일하게 변경하면 문제가 해결되었습니다. 또한 동일한 문자 인코딩이 필요합니다.
답변
이미 언급했듯이 이것은 순환 종속성 에 의해 발생합니다 . 언급되지 않은 것은 파이썬 타이핑 모듈을 사용하고 타입 에 주석을 달기 위해 클래스 만 가져올 때 Forward 참조를 사용할 수 있다는 것입니다 .
형식 힌트에 아직 정의되지 않은 이름이 포함 된 경우 해당 정의는 문자열 리터럴로 표현되어 나중에 확인할 수 있습니다.
의존성을 제거하십시오 ( 가져 오기 )
from my_module import Tree
def func(arg: Tree):
# code
하다:
def func(arg: 'Tree'):
# code
(제거 된 import
진술에 유의 )