본문 바로가기

Python

Python - Import

모듈 불러오기

import <모듈 이름>

 

이렇게 import한 다음 사용할 때는

<모듈 이름>.<모듈에서 사용하길 원하는 변수/함수/클래스 이름>

모듈 이름을 안 붙여주면 파이썬은 호출한 걸 지금 파일에서만 찾으려고 한다.

 

모듈에서 사용하는 것이 명확할 때

from <모듈 이름> import <함수/변수/클래스>, <함수/변수/클래스>

 

아래와 같이 쓰면 모듈에 있는 모든 요소를 import한다. 현재 파일에서 다른 것과 이름 충돌이 나면 알기 어려우니 비권장.

from <모듈 이름> import *

 

from .. import .. as 새 이름

여러 모듈을 import하다 불러낸 것들끼리 이름 충돌이 나거나 또는 사용하려고 불러낸 모듈/함수/변수/클래스의 이름이 너무 길면 새로 이름을 줄 수 있다.

from my_module import my_func as f1

이러면 이제 my_module의 my_func은 f1으로 호출된다.

 

패키지를 import할 때

import <패키지 이름>.<모듈 이름>

패키지 있는 함수를 사용할 때

<패키지 이름>.<모듈 이름>.<함수 이름>

이렇게 써서 호출해야 된다.

 

패키지 폴더 안에는 패키지 초기 설정을 가능하게 해주는 __init__.py파일이 있다. 이 파일은 패키지가 import 될 때 자동으로 실행된다. 만일 여기에 총 경로를 줄여주는 코드가 들어있다면 <패키지 이름>.<함수 이름> 정도로 줄일 수 있다.


import를 할 때 파이썬이 하는 일

sys.modules, built-in modules, sys.path 순으로 탐색면서 import한 모듈/패키지를 찾는다

1. sys.modules

This is a dictionary that maps module names to modules which have already been loaded. (공식 문서)

이미 import된 적이 있는 모듈/패키지들을 저장하는 딕셔너리. 한 번 import 된 모듈과 패키지는 파이썬이 또 다시 찾아 헤메지 않도록 기능한다. 새로 import하는 모듈은 여기서 찾을 수 없다.

sys.modules를 출력하면 나오는 dict의 생김새

value의 type을 체크해보면 <class 'module'> 이다.

2. buit-in modules

파이썬에서 제공하는 공식 라이브러리들. 이미 파이썬에 포함되어 있다

3. sys.path

경로를 나타내는 문자열 요소들을 가지고 있는 리스트. 어떤 형태의 경로를 갖고 있는지 궁금해서 출력해봤다.

sys.path를 출력하면 나오는 list의 생김새

이 외에도 아래 이미지의 경로와 유사한 형태의 여러 문자열 요소가 있었다. 자세히 보면 알 수 있겠지만 모듈이나 패키지 하나하나의 경로가 아니다. 파이썬path를 기반으로 한, 모듈과 패키지가 들어있는 여러 디렉토리의 경로이다.

 

sys.path 공식 문서에는 pythonpath라고만 되어있는 부분이 있어서 확인하려고 환경변수 창에 들어갔다. 내가 예전에 파이썬 두 버전을 깔았다가 하나를 지우면서 후속 조치를 깔끔하게 취하지 않은 바람에 시스템 변수와 사용자 변수의 path에 들어있는 파이썬 버전이 다르게 되어있었다. 사용자 변수가 우선 적용이라는 걸 이렇게 눈으로 보게 된 것도 좋고, 문제가 생기기 전에 찾고 수정해서 다행이다...

 

위의 이미지들은 아래의 코드로 출력한 내용의 일부이다.

import sys

print(sys.modules)
print(sys.path)

sys는 built-in 모듈이지만, sys.modules에 'sys' : <module 'sys' (built-in)>이 들어있는 것을 보아 이 때 sys를 import하면서 sys.modules에서 찾아왔을 것이다.


절대 경로(absolute path)

프로젝트의 최상단 디렉토리를 기준으로 한다. 단순한 방법이지만 무조건 최상단부터 나열해야되니 조금 번거롭다.

파이썬 앱의 직접 실행 파일에서는 이 방법만 가능하다. 아래 예제 설명에서 그 이유를 확인할 수 있다.

cf. C드라이브부터 시작하는 전체 경로를 넣는 게 아니다.

상대 경로(relative path)

import의 주체가 되는 모듈 파일의 위치를 기준으로 한다. 패키지 안에서 모듈끼리 import할 때 유용하다.


예제

패키지 내외에서 패키지 내 모듈 import하기

예제 구조

main.py는 아래와 같다.

if __name__ == '__main__':
    print(add_and_multiply(1,2))

main.py에서 모듈 불러오기

만일 main.py에서 상대 경로로 import add_and_multiply를 시도하면 에러가 난다.

from .calculator.add_and_multiply import add_and_multiply

main.py에서 상대 경로로 import 시도했을 때 에러

이런 문제가 생기는 이유는 main.py의 실행부에 있는 if __name__ == '__main__': 때문이다.

__name__은 현재 모듈의 이름을 담고 있는 내장 변수이다. 만일 sys 모듈 파일 안에 print(__name__)을 넣고 정상적인 환경에서 모듈을 실행한다면 sys가 출력된다. 참고 링크

하지만 직접 실행된 모듈의 경우 __name__은 __main__이라는 값을 가진다. 만일 main.py를 직접 실행하지 않고 다른 곳에서 import를 했을 때는 __name__이 main이었겠지만, 지금 예제의 경우 main.py를 직접 실행했으니 __main__이 되었다. 참고 링크 __name__에 대해 더 알아보기 위해서는 namespace라는 개념에 대해 더 알아보아야 겠다. 참고 링크

상대 경로는 현재 모듈을 기준으로 삼는데, main과 __main__은 다른 값이니 현재 디렉토리 구조를 기준으로 다른 모듈을 import해올 수 없다. 그래서 파이썬 앱의 main 모듈로 쓰이는 모듈 파일에서는 항상 절대 경로를 사용해 다른 모듈들을 import해와야 된다. 참고 링크

이런 __name__의 특성을 이용하여, 어떤 모듈에 if __name__ == '__main__': 조건문 안에 직접 실행 때만 작동할 코드를 넣어둘 수 있다. 그러면 이 모듈이 import되는 대상일 때는 __name__이 모듈의 이름일테니, __main__ 조건문 안의 코드가 실행되지 않는다.

 

지금 예제의 경우 main.py를 직접 실행하고 있으니 이 파일에서 다른 모듈을 import할 땐 아래와 같은 절대 경로로 넣어야 된다. main.py가 calculator 폴더와 같은 위치에 있으니 from calculator로 시작한다.

from calculator.add_and_multiply import add_and_multiply

패키지 안에서 다른 모듈 불러오기

add_and_multiply.py에서 multiply.py에 있는 multiply 함수를 가져올 때 상대 경로와 절대 경로 둘 다 가능하다.

add_and_multiply 모듈이 import되는 대상일 때, multiply 모듈을 import하는 주체가 되는 add_and_multiply 모듈의 __name__은 add_and_multiply이기 때문이다. 직접 실행이 아니니 add_and_multiply.py 파일의 위치를 기준으로 상대 경로를 설정하는 데 문제가 없다.

from .multiplication import multiply	# relative path

from calculator.multiplication import multiply	# absoulte path

 

'Python' 카테고리의 다른 글

Python - bcrypt, pyjwt  (1) 2021.02.07
Python - pyjwt v2.0.0 업데이트에 따른 이슈  (0) 2021.02.02
Python - list vs tuple, set vs dictionary  (0) 2021.01.15
Python - Dictionary  (0) 2021.01.15
Python - Set  (0) 2021.01.15