일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- docker
- DP
- JavaScript
- **kwargs
- django
- decorator
- 해시충돌
- Python
- RESTfulAPI
- 윈도우우분투듀얼부팅
- 파이썬
- 리스트컴프리헨션
- clone-coding
- wecode
- 알고리즘
- 파이썬입출력
- *args
- clone coding
- 자료구조
- bcrypt
- 파이썬문법
- CSS
- 인증인가
- 자바스크립트
- QuerySet
- 파이썬리스트컴프리헨션
- promise
- 코딩테스트파이썬
- 백준
- 인터넷 네트워크
- Today
- Total
개발기록장
[Python] 파이썬 모듈과 패키지(2) - 절대경로와 상대경로 + ImportError 본문
이전 글 읽기
2021/01/16 - [TIL/알고리즘 with 파이썬] - [Python] 파이썬 모듈과 패키지(1) - 개념
이전 글에서 파이썬 모듈과 패키지에 대해 알아보았다.
이번 글에서는 calculator라는 패키지를 직접 만들어보면서 import 시 알아야 할 절대 경로와 상대 경로에 대해 알아보자.
1. Absolute path vs Relative path
- 절대 경로와 상대 경로 차이점
절대 경로는 import하는 - 파일이나 경로에 상관 없이 항상 프로젝트의 최상위 디렉토리에서 시작되는 경로를 말한다.
절대 경로를 사용하면 사용하고자 하는 모듈과 그 모듈의 패키지 구조를 알기 쉽다는 장점이 있다.
반면, 경로가 길어진다는 단점도 있다.
상대 경로는 import하는 위치를 기준으로 시작되는 경로를 말한다.
상대 경로로 나타낼 때 '.'은 import가 선언되는 파일의 현재 위치를 의미하고 '..'은 현재 위치의 상위 디렉토리를 의미한다.
상대 경로를 사용하면 절대 경로를 사용할 때에 비해 코드는 짧아질 수 있지만,
경로를 헷갈리기 쉽고 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점이 있다.
예시)
# 절대 경로
from package2.subpackage1.module5 import func1
# 상대 경로
# package2/module3.py 에서 import
from .subpackage1.module5 import func2
# subpackage1/module5.py 에서 import
from ..module4 import class4
2. 상대 경로와 에러
우선 예제로 살펴 볼 my_project라는 프로젝트의 calculator 패키지 구조와 각 모듈의 내용은 아래와 같다.
# main.py
from .calculator.add_and_multiply import add_and_multiply
if __name__ == '__main__':
print(add_and_multiply(1,2))
# add_and_multiply.py
from .multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
# multiplication.py
def multiply(a,b):
return(a*b)
main.py를 실행시키면 아래의 에러가 난다.
$ python3 main.py
Traceback (most recent call last):
File "main.py", line 6, in <module>
from .calculator.add_and_multiply import add_and_multiply
ImportError: attempted relative import with no known parent package
부모 패키지도 모르는데(=스크립트로 직접 실행하는데) 감히 상대경로 import를 시도했다 라는 뜻이다.
python3 부터는 파이썬 자체에서 패키지와 모듈을 가져와 함수를 쓰는 곳에서는 상대경로로 접근자체가 불가능하게 막아놓았다.
즉 스크립트로 직접 실행할 때가 아닌 경우는 상대경로로 import할 수 없다는 얘기다. (파이썬 공식 문서 참고)
** 참고로 패키지 안에 있는 모듈을 스크립트로 실행하는 것은 안티패턴이라고 한다..
- 해결 방안 1
상대 경로로 import 된 것을 절대 경로로 바꿔서 실행해보자.
- 해결 방안 2
__name__ 변수를 이용하는 방법.
if __name__ == '__main__': 이 구문의 의미는 '만일 이 파일이 인터프리터에 의해서 실행되는 경우라면' 라는 의미이다.
따라서 '인터프리터에 의해서 실행되는 경우' 일 때만 상대경로로 import 되게 설정하는 방법도 있다.
>> 딱 봐도 좋아 보이진 않는다...여기서는 __name__ 변수를 어떻게 활용하는지만 보고, 이러니 저러니 그냥 절대경로를 쓰자..
참고 링크
blog.potados.com/dev/python3-import/
'TIL > Python' 카테고리의 다른 글
[Python] 파이썬 특수문법 - 중첩 함수와 데코레이터 (0) | 2021.01.19 |
---|---|
[Python] 파이썬 모듈과 패키지(1) - 개념 (0) | 2021.01.16 |
[Python] 가변 인수와 가변 키워드 인수 + 파라미터 순서 (0) | 2021.01.14 |
[Python] Argument 설정에 따른 함수 호출과 default value parameter (0) | 2021.01.14 |
[Python3] 파이썬 완전 기본 문법 정리 (데이터 타입, 입출력, 연산자) (0) | 2021.01.13 |