프로그래밍을 시작한 지 얼마 되지 않다보니 간단한 에러로 보이는데 기본적인 개념이 부족해서 ImportError: attempted relative import with no known parent package 에러가 발생해서 많은 시간을 소모해서 해결과정을
기록하게 됐습니다.
구글링을 열심히 했지만, stackoverflow 내용이 잘 이해가 되지 않았습니다. 왜 이렇게 해결이 안 되는 건지 도저히 이해가 가지 않아서
하루가 지나고 천천히 정리하다보니 조금 씩 정리가 되었습니다.
대부분의 자료들이 영어로 되어 있다보니 이해가 늦어서 제가 보았던 해결책들을 한글로 번역해서 자료를 만들게 됐습니다.
ImportError: attempted relative import with no known parent package
에러가 발생한 상황
위와 같은 디렉토리 구조를 가진 프로젝트가 있습니다.
package/mymath.py 에는 다음과 같은 함수가 있습니다.
def my_add(x,y):
return x+y
package/package/mypath.py 에는
from ..mymath import my_add
a = my_add(1,2)
print(a)
다음과 같이 구현이 되어 있습니다.
여기서 mypath.py 를 터미널에서 실행시키기 위해 터미널의 현재위치를 cd package/package 를 통해 이동합니다.
그리고 mypath.py를 실행시키면 위와 같은 에러가 발생합니다.
에러가 발생한 원인
-> 이제 한 번 어떤 상화에서 이런 에러가 발생하는지 확인을 했으니, 에러가 발생한 원인을 찾아보도록 하겠습니다.
원인은 python interpreter는 relative import의 module 위치를 정할 때 즉, 기준이 되는 모듈의 위치를 정할 때
__name__속성에 의해 결정됩니다.
이미 알고 계신분들도 있고, 잊고 계신 분들도 있겠지만 터미널에서 직접 python 파일을 실행시킬 때 __name__ == '__main__' 이 됩니다. 그러면 당연히 __main__이라는 모듈의 위치를 파이썬 interpreter는 알 수가 없기 때문에 에러가 발생합니다.
- module 과 package 개념이 헷갈리시는 분은
http://myjorney.tistory.com/19 여기서 개념을 확인하시면 됩니다.
해결 방안
1. python 의 -m 옵션을 이용한다.
-m mod : run library module as a script (terminates option list)
-m 옵션은 모듈을 스크립트로 수행할 때 쓰는 옵션입니다.(즉, 모듈이야 라고 말해주는 거죠.)
1) 먼저 프로젝트 root directory인 test2 디렉토리로 이동합니다.
2) 그리고 python3 -m package.package.mypath 를 입력하여 실행시키면 해결됩니다.
pakage 구조를 알려줬기 때문에 python은 상대경로를 찾을 수 있습니다.
참조: https://www.napuzba.com/story/import-error-relative-no-parent/
2. python의 절대경로를 이용한다.
if __name__ == '__main__':
if __package__ is None:
import sys
from os import path
print(path.dirname( path.dirname( path.abspath(__file__) ) ))
sys.path.append(path.dirname( path.dirname( path.abspath(__file__) ) ))
from mymath import my_add
else:
from ..mymath import my_add
a = my_add(1,2)
print(a)
__name__ == '__main__' 은 터미널에서 스크립트 형태로 실행시켰을 때는 절대경로를 이용해서 import 해주고
그가 아닌 경우 상대경로를 이용합니다. print() 함수로 디렉토리 위치를 확인하면서 하면 훨씬 좋습니다.
정리하고 나니 마음이 너무 편하네요 :)
감사합니다!
도움이 되셨으면 좋겠습니다.
'Computer Engineering > My Stack Overflow' 카테고리의 다른 글
Airflow Error - Triggerer's async thread was blocked for xx seconds, likely by a badly-written (0) | 2023.03.16 |
---|---|
Airflow(에어플로우) could not queue task issue (0) | 2022.11.22 |