본문 바로가기
Python

[Python] Ex: Relative Path Import 시 주의할 점

by ds31x 2024. 6. 4.

다음은 main script 등에서 relative path import를 사용할 때,
__name__을 기준으로 삼기 때문에 주의해야 점을 발생 가능한 문제를 예를 들어서 설명하는 문서임.


예제 디렉토리 구조

my_package/
    __init__.py
    main.py
    subpackage/
        __init__.py
        module_a.py
        module_b.py

코드 예제

1. module_a.py:

# my_package/subpackage/module_a.py
def greet():
    return "Hello from module_a"

2. module_b.py:

# my_package/subpackage/module_b.py
from .module_a import greet

def greet_from_b():
    return greet()

3. main.py:

# my_package/main.py
from subpackage.module_b import greet_from_b

if __name__ == "__main__":
    print(greet_from_b())

상황 설명

  • module_a.py는 간단한 함수를 가지고 있음.
  • module_b.py는 상대 경로로 module_a를 임포트하고 있음.
  • main.pymodule_b를 임포트하고 함수를 호출함.

참고: __file____name__의 차이

  • __file__은 모듈 파일의 경로를 나타냄.
    • 예를 들어, my_package/subpackage/module_a.py__file__ 값은 이 파일의 경로가 됨.
  • __name__은 모듈의 이름을 나타냄.
    • 이는 모듈이 어떻게 임포트되었느냐에 따라 달라짐.

main.py를 직접 실행하는 경우

my_package 디렉토리에서 python main.py 명령어를 실행하면:

  • main.py__name__"__main__"이 됨.
  • main.py에서 from subpackage.module_b import greet_from_b 구문이 실행될 때,
    module_b__name__"subpackage.module_b"가 됨.
  • module_b.py 내부에서 from .module_a import greet 구문이 실행될 때,
    ."subpackage"을 의미함. 따라서 module_a가 제대로 임포트됨.

잘못된 실행 방법

module_b.py를 직접 실행하려고 하는 경우:

python my_package/subpackage/module_b.py

이 경우:

  • module_b.py__name__"__main__"이 됨.
  • 상대 경로 임포트 from .module_a import greet가 실패함.
  • 이는 .이 더 이상 subpackage를 가리키지 않기 때문임. __main__은 패키지 컨텍스트를 잃게 됨.

올바른 실행 방법

패키지 내의 모듈을 실행하려는 경우:

python -m my_package.subpackage.module_b

이 경우:

  • module_b.py__name__"my_package.subpackage.module_b"가 됨.
  • 상대 경로 임포트 from .module_a import greet가 정상적으로 작동함.

요약

  • __name__은 모듈의 이름을 나타내며, 이는 모듈이 어떻게 실행되었는지에 따라 달라짐.
  • 상대 경로 임포트는 __name__을 기준으로 동작하므로, 직접 실행할 때는 패키지 컨텍스트가 유지되지 않아 문제가 발생함.
  • python -m package_name.module_name으로 실행하면 모듈이 패키지의 일부로 인식되어 상대 경로 임포트가 정상적으로 작동함.

이렇게 __file__이 아닌 __name__을 기준으로 동작하는 이유는 파이썬의 임포트 시스템이 모듈의 위치와 관계없이 모듈의 이름을 기준으로 동작하도록 설계되었기 때문임.


같이 보면 좋은 자료들

https://dsaint31.tistory.com/528

 

[Python] Module Search Path and sys.path

Module Search Path and sys.path 1. Module Search PathPython 에서 module을 찾는 경로 (Module Search Path)는 다음의 순서별로 우선권을 가짐.home directory of the program (main script file이 있는 위치 or python shell이 수행된

dsaint31.tistory.com