본문 바로가기

TIL

[TIL] #12. Absolute path & Relative path

Absolute path

Absolute path는 말 그대로 절대경로를 말하며 import하는 파일이나 경로에 상관없이 항상 동일한 경로를 말한다. linux에서 말하는 절대경로와 같은 의미를 가진다. 쉽게 생각하면 import하고자 하는 대상이 위치한 경로를 최상위 경로부터 모두 표기하여 import하는 방식이다. 일반적으로 local package를 import할 때는 절대경로를 사용한다.

다음과 같은 구조를 가진 디렉토리가 있다고 치자.

.
+-- project
         +-- main.py
         +-- package1
         |       +-- module1
         +-- package2
                 +-- module2
                 +-- module3
                 +-- subpackage1
                           +-- module4

여기서 module1을 절대경로를 사용하여 import 한다고 하면

from package1 import module1

module1의 경로는 project/package1/module1.py 로 나타낼 수 있다. Python에서는 project.package1.module1.py 로 나타낼 수 있다. project안에서 import를 하는 것이므로 project 는 생략이 가능하다. 이번에는 module4를 절대경로를 사용하여 import해보면

from package2.subpackage1 import module4

Relative path

Relative path는 상대경로를 말하며 절대경로로 표기했을 때 경로명이 길어지는 것을 방지할 수 있다. import 대상의 최상위 경로부터 표기하는 것이 아니라 import하는 위치를 기준으로 경로를 표기한다. 일반적으로 local package안에서 다른 local package를 import할 때 상대경로를 사용한다.

위 디렉터리 구조에서 module2에서 module4를 상대경로를 사용하여 import한다고 하면

# 현재 경로 : package2/module2
from .subpackage1 import module4

절대경로를 사용하여 import 하면

from package2.subpackage1 import module4

상대경로를 사용하면 import할 때 명시할 경로의 길이가 짧아지지만 헷갈리기도 하고 모듈의 현재 경로가 바뀔 때마다 상대경로도 바뀌기 때문에 문제가 발생할 수 있다. 그렇기 때문에 모듈 import할 때는 절대경로를 사용하는 것이 좋다.

Relative path를 사용할 때는 언제일까?

+-- calculator
|        +-- __init__.py
|        +-- add_and_multiply.py
|        +-- multiplication.py
+-- main.py

위와 같은 디렉토리가 있을 때 main.py 에서 add_and_multiply.py모듈을 상대경로로 import하면 (모듈안에 같은 이름을 가진 메소드 import하는 것!)

from .calculator.add_and_multiply import add_and_multiply

다음과 같은 에러가 발생한다.

Traceback (most recent call last):
  File "main.py", line 5, in <module>
    from .calculator.add_and_multiply import add_and_multiply
ImportError: attempted relative import with no known parent package

부모 패키지를 모른채로 상대경로로 import를 시도했다는 에러메시지가 출력되었다. main.py 기준으로 상대경로를 맞게 작성하여 import 했는데 왜 에러가 나는 것일까?? Python 공식문서에서 Intra-Package References 를 보면

Note that relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application must always use absolute imports.

즉, 모듈 자체를 실행하는 경우에는 그 모듈안에 다른 모듈을 import할 때 반드시 절대경로로 import해야한다. 다시 말하면, 실행하는 파이썬 스크립트 파일안에서는 다른 모듈을 import할 경우 무조건 절대경로로 import해야 정상적으로 동작한다. 이 정도면 상대경로 import를 굳이 왜 쓰나 싶기도 하다.🤔모듈이 직접 실행되는 모듈이 아닌 경우에는 상대경로 import를 허용한다.

이번에는 add_and_multiply.py 에서 multiplication.py모듈의 메소드를 상대경로로 import하고 main.py 를 실행해보자.

from .multiplication import multiply

이번에는 정상적으로 실행된다. 그 이유는 add_and_multiply 모듈은 직접 실행되는 모듈이 아니기 때문이다. 여기서 실행되는 모듈을 main.py 이기 때문에 main.py 모듈을 제외한 다른 모듈들은 상대경로 import를 포함하고 있어도 상관이 없는 것이다.

References

'TIL' 카테고리의 다른 글

[TIL] #14. Framework vs Library  (0) 2021.03.28
[TIL] #13. __init__.py  (0) 2021.03.23
[TIL] #11. Module&Package  (0) 2021.03.23
[TIL] #10. Function Parameters  (0) 2021.03.21
[TIL] #9. Python 기초 문법  (0) 2021.03.19