[파이썬] circular import error

 django rest framework 를 사용하다가 

circular import error를 만나게 되었다. 


문제의 발단은 

Employee model과 Job model은 외래키로 연결이 되어 있다.

Employee serializer에서 Job serialzer를 참조해야하고

반대로 Job serializer에서 Employee serializer를 참조해야하는 상황이 발생했다.

사실 잘 발생할 일이 없는 일이지만 커스터마이즈를 최대한 하려다보니 마주친 에러였다.

django rest framework를 너무 깊게 들어가기엔 복잡하니

간단하게 파일 2개를 생성해서 당시상황을 재현해보자.


1
2
3
4
5
6
7
8
9
10
11
12
# first.py
 
from second import E
 
class A():
    pass
 
class B(E):
    pass
 
class C():
    pass
cs


1
2
3
4
5
6
7
8
9
10
11
12
# second.py
 
from first import C
 
class D():
    pass
 
class E():
    pass
 
class F(C):
    pass
cs


현재폴더에서 파이썬를 실행한 후

import first

를 입력하면 아래와 같은 Import Error가 난다.

1
ImportError: cannot import name 'C' from partially initialized module 'first' (most likely due to a circular import)
cs


1. 가장 기본적이고 확실한 방법은 파일을 분리하는 방법이다.

  • first.py의 C클래스를 다른 파일에 넣던지
  • first.py의 B(E) 클래스를 다른 파일에 넣던지
  • second.py의 E클래스를 다른 파일에 넣던지
  • second.py의 F(C)클래스를 다른 파일로 옮긴다.

하지만 파일분리가 애매할 경우가 발생할 수 있다.
2. 그럴때는 코드의 순서를 좀 바꿔준다.

아래 코드를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
#first.py
 
class A():
    pass
 
 
class C():
    pass
    
    
from second import E
class B(E):
    pass
cs


1
2
3
4
5
6
7
8
9
10
11
# second.py
 
class D():
    pass
    
class E():
    pass
 
from first import C
class F(C):
    pass
cs


위와같이 first.py에서 import 당하게 되는 C 클래스가 

from second import E 위에 위치시켜주고 

second.py에서도 import 의 위치를 조금 변경시켜주면 circular import 에러를 피할 수 있다.

기본적으로 파이썬은 모든 import 문은 가장 위에 작성하는것이 권장되지만,

가끔 라이브러리의 코드를 보다보면 중간에 import 문이 작성되는경우를 보게 되는 경우도 있다.

필요한 시점에 import를 작성하면 circular import 에러를 피할 수 있다.

No comments:

Post a Comment