Debugging Sparrow

Python3 m option and Import

2019/02/07 Python3 Import m option

Python3로 개발을 하다 보면 패키지 내의 모듈을 바로 실행하고 싶은 욕망에 빠져듭니다. Main 진입점이 있는 여타 언어와 달리 python 파일 자체가 스크립트처럼 사용할 수 있어서 그럴 것입니다. 그러나 막상 만나는 건 Import Error. 그리고 허둥지둥 구글링을 해보죠. m 옵션을 주고 경로 대신 패키지 형식을 입력하여 실행하면 된다고 합니다. python3 -m foo.bar.baz로 해보니 실행이 됩니다. m 옵션이 어떤 역할을 하기에 가능할까요?

아래는 예시 입니다.

Package
1
2
3
4
5
6
7
project_root/
foo/
__init__.py
qux.py
bar/
__init__.py
baz.py
baz.py
1
from foo import qux
qux.py
1
print("Qux Imported.")
Run in proejct_root
1
2
3
4
5
6
7
8
9
10
11
$ pwd
project_root

$ python3 foo/bar/baz.py
Traceback (most recent call last):
File "foo/bar/baz.py", line 1, in <module>
from foo import qux
ModuleNotFoundError: No module named 'foo'

$ python3 -m foo.bar.baz
Qux Imported.

Import

m 옵션에 대해 설명을 하기 전에 Python3의 Import에 대해서 알아봐야 합니다. 크게 두 가지 방식이 있습니다.

절대 경로 임포트(Absolute Import)

먼저 절대 경로 임포트 입니다. 라이브러리를 활용할떄 일반적으로 사용하는 Import 문법으로 보시면 됩니다.

Python3
1
2
import requests
from foo import bar

절대 경로 임포트 시 패키지를 sys.path에서 찾습니다. sys.path에 프로젝트의 Root Path가 없는 경우가 위에서 흔히 일어나는 Import Error 상황입니다.
패키지 내 모듈을 바로 실행하면 해당 모듈의 패키지가 sys.path에 들어가기 때문입니다.

명시적 상대 경로 임포트(Explicit Relative Import)

다음은 명시적 상대 경로 임포트 입니다.

Python3
1
2
from .foo import bar
from ..foo import bar

명시적 상대 경로 임포트 시 패키지를 현재 실행 중인 모듈의 __package__와 __name__값을 기준으로 찾습니다. 이때 __package__가 우선순위를 가집니다.
패키지 내 모듈을 바로 실행하면 __package__값은 None이고 __name__은 __main__이 되기 때문에 명시적 상대 경로의 기준이 없어 Import Error가 나타납니다.

암묵적 상대 경로 임포트(Implicit Relative Import)

Python2에는 있었으나 Python3부터 사라진 기능입니다. 따로 내용을 넣진 않겠습니다만 궁금하시면 찾아보셔도 좋습니다.

m option

m 옵션은 모듈을 스크립트처럼 활용할 수 있게 해주는 옵션입니다. 이 말이 무슨 말이냐 하면 python3 -m foo.bar.baz로 실행 시 sys.path엔 ‘’가 들어가고 __package__값은 foo.bar가 됩니다.
프로젝트의 Root Path에서 m 옵션을 활용한다고 했을 때 sys.path에 ‘’가 들어가므로 절대 경로 임포트가 가능하며 __package__값도 foo.bar가 되어 명시적 상대 경로 임포트도 가능해집니다.

결론

m 옵션이 만능열쇠처럼 쓰여 있지만 테스트 목적 외에 사용하지 않는 게 좋습니다. 모듈을 항상 스크립트처럼 쓰고 싶은 건 아닐 테니까요. 그리고 사실 테스트를 위해서도 unit test가 더 적합해 보입니다.

Author: dbgsprw

Link: https://dbgsprw.github.io/2019/02/07/Python3-Import/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
쿠버네티스(Kubernetes, k8s) 용어 정리
NextPost >
JWT RS256
CATALOG
  1. 1. Import
    1. 1.1. 절대 경로 임포트(Absolute Import)
    2. 1.2. 명시적 상대 경로 임포트(Explicit Relative Import)
    3. 1.3. 암묵적 상대 경로 임포트(Implicit Relative Import)
  2. 2. m option
  3. 3. 결론