이미지 출처: https://wikidocs.net/192339
오늘은 저번 시간 모듈 이어서 패키지 작성 및 사용법에 대해 알아보겠습니다. 패키지도 어렵지 않습니다. 모듈을 모아놓은 폴더를 패키지라고 생각하시면 됩니다. 우리가 공부했던 파일들 이것들이 재사용 가능하다면 하나의 모듈이라고 볼 수 있습니다. 이것들의 합을 Python 기본 패키지라고 볼 수 있습니다. 모듈의 분할된 개별적인 모듈이 모여서 하나의 패키지가 됩니다.
패키지(Package) 개념
저는 인프런에서 제공받은 sub 폴더를 저희가 학습하던 폴더에 넣었습니다. 실습까지 하면 좋겠지만 내용을 보고 패키지의 작성과 사용법만 익히셔도 괜찮습니다.
sub 폴더에는 sub 1 폴더와 sub 2 폴더가 있는데 살펴봅시다.
sub1 폴더(module1.py)
import sys import inspect # from ..sub2 import module2 # module1.py def mod1_test1(): print ("Module1 -> Test1") print("Path : ", inspect.getfile(inspect.currentframe())) def mod1_test2(): print ("Module1 -> Test2") print("Path : ", inspect.getfile(inspect.currentframe()))
sub2 폴더(module2.py)
sub1폴더의 module1.py파일과 같지만 서로 위치된 디렉토리 경로, 실행경로 출력되는 프린트문이 다른 것을 확인할 수 있습니다.
import sys import inspect # from ..sub1 import module1 # module2.py def mod2_test1(): print ("Module2 -> Test1") print("Path : ", inspect.getfile(inspect.currentframe())) def mod2_test2(): print ("Module2 -> Test2") print("Path : ", inspect.getfile(inspect.currentframe()))
이제 외부에 있는 패키지들을 가져와서 실행해봅시다.
예1
# sub패키지 안에 sub1 이라는 패키지 안에 모여있는 많은 모듈중 module1을 가져온다. # 저번처럼 append를 쓰지 않아도 같은 경로나 다른위치에 있는것을 찾아갈 수 있다. import sub.sub1.module1 # sub패키지의 sub2에 modul2를 가져오기 import sub.sub2.module2
사용
# mod1_test1()은 메소드 이름 # 서로 다른 경로에 있지만 같은 폴더에 있는 파이썬 파일에 모듈의 두개의 메소드를 각각 호출 # 메소드의 프린트문과 파일위치가 출력된다. sub.sub1.module1.mod1_test1() >>> Module1 -> Test1 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub1\module1.py sub.sub1.module1.mod1_test2() >>> Module1 -> Test2 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub1\module1.py sub.sub2.module2.mod2_test1() >>> Module2 -> Test1 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub2\module2.py sub.sub2.module2.mod2_test2() >>> Module2 -> Test2 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub2\module2.py
예2
import sub.b.d.e.sub1.module1 처럼 depth가 길어지면 쓰기 비효율적이다. 이럴 때 alies를 사용하면 효율적으로 코딩할 수 있다.
# m2로 alies하는 경우 간편하게 불러올 수 있다. from sub.sub1 import module1 from sub.sub2 import module2 as m2 # alies module1.mod1_test1() module1.mod1_test2() m2.mod2_test1() m2.mod2_test2() >>> Module1 -> Test1 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub1\module1.py sub.sub1.module1.mod1_test2() >>> Module1 -> Test2 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub1\module1.py sub.sub2.module2.mod2_test1() >>> Module2 -> Test1 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub2\module2.py sub.sub2.module2.mod2_test2() >>> Module2 -> Test2 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub2\module2.py
예3
*로 import를 하면 sub 1이라는 경로 패키지 안에 있는 모든 모듈을 가져오기에 내가 필요로 하는 것을 가져오는 것이 좋다. 불빌요한 작업을 하게 할 필요는 없기에 될 수 있으면 사용하지 않는다. 이런것들이 누적되면 메모리를 차지하겠죠?
# 현재 sub1안에 modul1파일뿐이다. 파일이 10개 있으면 모두 가져온다는 뜻 from sub.sub1 import* from sub.sub2 import*
module1.mod1_test1() module1.mod1_test2() module2.mod2_test1() module2.mod2_test2() >>> Module1 -> Test1 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub1\module1.py sub.sub1.module1.mod1_test2() >>> Module1 -> Test2 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub1\module1.py sub.sub2.module2.mod2_test1() >>> Module2 -> Test1 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub2\module2.py sub.sub2.module2.mod2_test2() >>> Module2 -> Test2 >>> Path : C:\Users\yount\Desktop\Python +\sub\sub2\module2.py
모듈을 가져올 때는 풀네임으로는 잘 가져오지 않습니다. from 절을 통해 정확히 패키지의 depth 경로를 찾아가서 내가 사용하고 싶은 모듈만 정확히 import하고 alies까지 사용하면 간단합니다.
__init__.py 파일이 패키지마다 하나씩 꼭 들어가 있습니다. 저희 sub 폴더에도 있습니다.
__pycache__라는 파일도 있을 텐데요. 참고로 이거는 런타임 환경 때 파일의 빠른 실행을 위해서 파이썬엔진이 만드는 것입니다. 지우셔도 됩니다.
__init__.py는 python3.3부터는 없어도 패키지로 인식 -> 단, 하위 호환을 위해 작성 추천
여러분이 어떤 파일을 만들고 이걸 패키지로 사용하고 싶다면 파이썬에게 이 파일이 패키지라는 것을 인식시켜 주어야 합니다. 그때 비어있는 __init__.py 파일을 만들어야 합니다.
현재 버전은 없어도 상관없지만 다른 이용자가 만약 내가 만든 패키지를 사용하는데 버전이 낮아 호환이 되지 않는다면 문제가 되겠죠.
sub1의 init.py
# 외부에서 module1.py를 import를 허가해주는 역할 __all__ = ['module1'] # 만약 이렇게 하고 module1을 가져오려고 하면 오류가 발생하겠죠. __all__ = ['module2'] from sub.sub1 import* >>> module 'sub.sub1' has no attribute 'module2'
sub2의 init.py
__all__ = ['module2']
전 세계의 많은 오픈소스를 보시면 __init__.py을 볼 수 있습니다. 저희는 왜 있는지 알고 있지만 모르고 파일을 보면 왜 폴더마다 저런 파일이 있는지 당황하겠죠😎
다음 시간에는 파이썬에서 발생하는 예외 처리 방법을 알아보겠습니다.