[PYTHON] 여러 경로의 모듈 import 하기 1
by cuore J동일/하위 폴더(경로)의 모듈을 from, import 하는법
1. 필요성
파이썬에서 위와 같이 game이란 project를 진행 한다고 가정해 보겠습니다. main.py 에서 여러 패키지(폴더) 안의 다른 모듈(##.py)을 import 할 수 있어야만 프로젝트를 완성할 수 있겠네요! 이번 글에서는 import에 관해 다루어 보겠습니다.
(ex. package1
패키지 안에 있는 module1_1.py
모듈을 불러와!)
2. main.py 에서 동일/하위 폴더(경로) 내 "모듈" 호출하기
같은 경로, 즉 같은 패키지에서 모듈을 가져오거나 (main.py▶module0.py ) 하위 경로 에서 모듈을 가져오는 방법(main.py▶package1.module1_1.py)을 아래 표에 모두 정리하였습니다. 아래와 같은 방법 중 어떤 걸 사용하여도 동일/하위 패키지의 모듈을 불러올 수 있어요. 하지만, 가독성을 높여주기 위해 저는 PEP8(파이썬 코딩 스타일 가이드라인) 에서 추천하는 방식을 추천드려요. 저도 가독성을 높이기 위해 아래 표에서 파란색 볼드 처리된 방식만 사용합니다. (취소선 은 아예 PEP8에서 쓰지 않길 권장합니다.) - 아래 링크를 한번 읽고 오시는걸 추천드립니다.
[참고] PEP8 스타일 가이드 (import 부분만 번역)
경로 | 호출 방식 | 사용 방법 |
동일 경로 (동일폴더) |
import 모듈 |
모듈.변수 모듈.함수 객체=모듈.클래스( ) |
import 모듈 as 별칭 | 별칭.변수 별칭.함수 별칭.클래스( ) |
|
from 모듈 import 변수 from 모듈 import 함수 from 모듈 import 클래스 from 모듈 import 변수, 함수, 클래스 |
변수 함수( ) 객체=클래스( ) |
|
변수 함수( ) 객체=클래스( ) |
||
from 모듈 import 변수 as 별칭1 from 모듈 import 함수 as 별칭2 from 모듈 import 클래스 as 별칭3 from 모듈 import 변수 as 별칭4, 함수 as 별칭5, 클래스 as 별칭6 |
별칭1, 별칭4 별칭2( ), 별칭5( ) 객체=별칭3( ) 객체=별칭6( ) |
|
하위 경로 (하위폴더) |
import 패키지.모듈 import 패키지.모듈1, 패키지.모듈2 |
패키지.모듈.변수 패키지.모듈.함수( ) 객체=패키지.모듈.클래스( ) |
import 패키지.모듈 as 별칭 | 별칭.변수 별칭.함수 별칭.클래스 |
|
from 패키지.모듈 import 변수 from 패키지.모듈 import 함수 from 패키지.모듈 import 클래스 from 패키지.모듈 import 변수, 함수, 클래스 |
변수 함수( ) 객체=클래스( ) |
|
변수 함수( ) 객체=클래스( ) |
||
from 패키지.모듈 import 변수 as 별칭1 from 패키지.모듈 import 변수 as 별칭2, 함수 as 별칭3, 클래스 as 별칭4 |
별칭1, 별칭2 별칭3( ) 객체=별칭4( ) |
3. main.py 에서 하위 폴더(패키지) 직접 불러오기
하위 패키지의 모듈을 직접 불러오기보단, 패키지를 한번 거쳐서 불러오는 방법도 있습니다. 여기서 조심해야 할 점은 import 패키지
와 from 패키지 import *
를 하면, 패키지의 __init__.py 만 가져 올뿐, 나머지 모듈은 가져오지 않습니다. __init__.py 의 사용법은 아래에 추가로 더 적겠습니다.
경로 | 호출 방식 | 사용 방법 |
하위 패키지 호출 main▶package1 |
from 패키지 import 모듈 |
모듈.변수 모듈.함수( ) 객체=모듈.클래스( ) |
from 패키지 import 모듈 as 별칭1 from 패키지 import 모듈2 as 별칭2, 모듈3 as 별칭3 |
별칭.변수 별칭.함수( ) 객체=별칭.클래스( ) |
|
imoprt 패키지 | __init__.py 사용 | |
__init__.py 사용법 | __init__.py 내부 내용 | main.py 에서 import 방법 |
import 패키지.모듈 | [main.py] import 패키지 패키지.모듈.변수 패키지.모듈.함수( ) 객체=패키지.모듈.함수( ) |
|
from 패키지 import 모듈 | ||
from . import 모듈 | ||
from .모듈 import * | [main.py] import 패키지 패키지.변수 패키지.함수( ) 객체 = 패키지. 클래스( ) |
|
from ..패키지 import 모듈 from ..패키지 import 변수, 함수, 클래스 from ..패키지 import * |
패키지 안에 하위패키지 |
[참고] __init__. py의 사용법
폴더 안에 __init__.py가있으면 이 폴더는 "패키지"로 인식됩니다. 보통 __init__.py는 비워져 있습니다. 참고로 python 버전 3.3 이상부터는 __init__.py가 없어도 패키지로 자동 인식이 되지만, 하위 버전에서도 호환되도록 두는 것이 좋습니다. 주의할 점은, 패키지 상위 경로의 모듈(ex. main.py)에서 import 패키지
또는 from 패키지 import *
로 불러올 시, __init__.py가 아닌 다른 모듈은 가져오지 않는다는 점을 알아야 합니다. 다음 예제를 봐주세요.
위에서 보시다시피 import 패키지로는 __init__.py만 가져 올뿐, module1_1.py 는 가져오지 않아 "module 'package1' has no attribute 'module1_1'"
라고 에러 메시지를 띄워줍니다. 여기서 __init__.py안을 다음과 같이 적으면 이 문제가 해결됩니다.
#__init__.py 절대경로 사용
import package1.module1_1 #import 패키지.모듈
from package1 import module1_1 #from 패키지 import 모듈
#__init__.py 상대경로 사용
from . import module1_1 #from . import 모듈
#위의 __init__.py 를 저장한 후 main.py
package1.module1_1.변수
package1.module1_1.함수( )
객체 = package1.module1_1.클래스( )
상대 경로는 후에 다루지만 간단히 설명드리면 .(점) 은 현재 패키지라는 뜻입니다.
그렇다면 추가로, main.py에서 패키지.모듈.클래스( )
가 아닌 바로 클래스( )
를 사용하기 위해선 어떻게 해야 할까요? 다음과 같이 __init__.py를 작성해 주면 됩니다.
#__init__.py
from .module1_1 import *
#module1_1.py
변수 = "변수실행"
def 함수():
print('함수실행')
class 클래스:
def __init__(self):
self.클래스변수 = '클래스변수'
#main.py
import package1
print(package1.변수)
package1.함수()
객체 = package1.클래스()
print(객체.클래스변수)
즉, from .module1_1 import *
를 해주게 되면, 패키지.변수, 패키지.함수, 패키지.클래스로 바로 접속이 가능하게 됩니다. 하지만, PEP8을 생각하면 이 방법은 쓰지 않는 게 좋겠네요!
여기까지 읽어주셔서 감사합니다. 다음 2편에서 더 자세히 적도록 하겠습니다.
블로그의 정보
cuore J
cuore J