변수, 함수 그리고 객체 등을 모아둔 파이썬 파일(.py)을 의미한다.
import 모듈이름
또는import 패키지 이름
예) my_module.py라는 모듈일 경우,
import my_module
my_module.my_func()
<모듈 이름>.<모듈에서 사용하길 원하는 변수/함수/클래스 이름>
과 같이 dot(점)을 활용하여 모듈의 메소드에 접근한다.
from
모듈이름
import변수/함수/객체
import라는 간단한 방법이 있는데,
왜 'from, import'방식이 또 있는걸까?
아래 코드를 보고 어떤 편리함을 가져다 주는지 알아보자.
from my_module import my_module_func, my_module_var
print(my_module_var)
my_module_func()
이점 : 모듈이름을 작성하지 않고 바로 함수나 변수 사용이 가능하다.
import my_module as m
m.my_func()
print(m.my_variable)
모듈이름이 너무 길거나(가독성 떨어짐)
서로 다른 모듈에서 불러온 함수의 이름이 동일할 수도 있다.
이럴 때 모듈의 이름을 바꿔주어 이름충돌
을 피한다.
Package
파이썬 파일(.py)들이 모인 집합을 패키지라고 한다.
Package는 일반 모듈 처럼 import 하여 사용한다.
단, package의 원하는 모듈을 .(점)
을 통해 import 한다..
# pkg의 mod1.py모듈 접근
import pkg.mod1
# pk1의 mod2.py모듈에서 func2를 import
from pkg.mod2 import func2
# pkg의 mod1.py모듈 안에 있는 func2 함수를 사용
pkg.mod1.func2()
func2()
Package가 import 될 때 초기 설정을 해줘야 할 때가 있다.
Package 안에 init.py 파일이 있으면
package가 import 될때 init.py 가 자동으로 실행된다.
이미 import된 모듈이나 패키지들의 디렉토리(폴더)를 의미한다.
차이점
1) 파이썬 프로그램을 실행시킬 때,가장 먼저
sys.modules
디렉토리 검색
2) 딕셔너리 자료구조로 모듈 경로들이 입력되어 있다.
import sys
print(sys.modules)
결과
{'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>, '_frozen_importlib': <module '_frozen_importlib' (frozen)>, '_imp': <module '_imp' (built-in)>, '_warnings': <module '_warnings' (built-in)>, '_frozen_importlib_external': <module '_frozen_importlib_external' (frozen)>, '_io': <module 'io' (built-in)>, 'marshal': <module 'marshal' (built-in)>, 'posix': <module 'posix' (built-in)>, '_thread': <module '_thread' (built-in)>, '_weakref': <module '_weakref' (built-in)>, 'time': <module 'time' (built-in)>, 'zipimport': <module 'zipimport' (frozen)>, '_codecs': <module '_codecs' (built-in)>, 'codecs': <module 'codecs' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/codecs.py'>, 'encodings.aliases': <module 'encodings.aliases' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/encodings/aliases.py'>, 'encodings': <module 'encodings' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/encodings/init.py'>, 'encodings.utf_8': <module 'encodings.utf_8' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/encodings/utf_8.py'>, '_signal': <module '_signal' (built-in)>, 'main': <module 'main' from '/Users/khh180cm/Documents/python_project/module/module.py'>, 'encodings.latin_1': <module 'encodings.latin_1' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/encodings/latin_1.py'>, '_abc': <module '_abc' (built-in)>, 'abc': <module 'abc' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/abc.py'>, 'io': <module 'io' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/io.py'>, '_stat': <module '_stat' (built-in)>, 'stat': <module 'stat' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/stat.py'>, '_collections_abc': <module '_collections_abc' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/_collections_abc.py'>, 'genericpath': <module 'genericpath' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/genericpath.py'>, 'posixpath': <module 'posixpath' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/posixpath.py'>, 'os.path': <module 'posixpath' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/posixpath.py'>, 'os': <module 'os' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/os.py'>, '_sitebuiltins': <module '_sitebuiltins' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/_sitebuiltins.py'>, 'site': <module 'site' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site.py'>}
차이점
:
1) 구조는 각 요소가 문자열 형태로 구성된 리스트다.
각 요소는 모듈이 있는 경로를 표시하고 있다.
2) 검색 순서sys.modules
->built-in modules
다음
import sys
print(sys.path)
결과
['/Users/khh180cm/Documents/python_project/module', '/Library/Frameworks/Python.framework/Versions/3.8/lib/python38.zip', '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8', '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages']
import sys
print(sys.modules)
아래와 같이 sys': <module 'sys' (built-in)
built-in modules 에서 sys 모듈을 찾고있다는 걸 알 수 있다.
{'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>, '_frozen_importlib': <module '_frozen_importlib' (frozen)>, '_imp': <module '_imp' (built-in)>, '_warnings': <module '_warnings' (built-in)>, '_frozen_importlib_external': <module '_frozen_importlib_external' (frozen)>, '_io': <module 'io' (built-in)>, 'marshal': <module 'marshal' (built-in)>, 'posix': <module 'posix' (built-in)>, '_thread': <module '_thread' (built-in)>, '_weakref': <module '_weakref' (built-in)>, 'time': <module 'time' (built-in)>, 'zipimport': <module 'zipimport' (frozen)>, '_codecs': <module '_codecs' (built-in)>, 'codecs': <module 'codecs' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/codecs.py'>, 'encodings.aliases': <module 'encodings.aliases' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/encodings/aliases.py'>, 'encodings': <module 'encodings' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/encodings/init.py'>, 'encodings.utf_8': <module 'encodings.utf_8' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/encodings/utf_8.py'>, '_signal': <module '_signal' (built-in)>, 'main': <module 'main' from '/Users/khh180cm/Desktop/calculator/test.py'>, 'encodings.latin_1': <module 'encodings.latin_1' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/encodings/latin_1.py'>, '_abc': <module '_abc' (built-in)>, 'abc': <module 'abc' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/abc.py'>, 'io': <module 'io' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/io.py'>, '_stat': <module '_stat' (built-in)>, 'stat': <module 'stat' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/stat.py'>, '_collections_abc': <module '_collections_abc' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/_collections_abc.py'>, 'genericpath': <module 'genericpath' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/genericpath.py'>, 'posixpath': <module 'posixpath' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/posixpath.py'>, 'os.path': <module 'posixpath' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/posixpath.py'>, 'os': <module 'os' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/os.py'>, '_sitebuiltins': <module '_sitebuiltins' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/_sitebuiltins.py'>, 'site': <module 'site' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site.py'>}
ex) 동일 패키지에서 다른 함수를 사용하는 경우
from . import class1
Q. main.py에서 상대경로로 add_and_mutiply 를 임포트 했을 때 발생하는 에러를 확인하고 main module 에서는 패키지의 모듈을 어떻게 임포트 해야하는지 설명하시오.
에러
ImportError: attempted relative import with no known parent package
from .calculator.add_and_multiply import add_and_multiply
if __name__ == '__main__':
print(add_and_multiply(1,2))
print(__name__)
print("ok")
상대경로로 모듈을 import하게 되면
시작기준점은 현재파일이 된다.
이것이 모든 문제를 야기시킨다.
(참고) 내가 작성한 파일(모듈)명이 main.py이든, test.py이든 practice.py이든 not_main.py이든
내가 실행(F5)시키는 바로 그 파일이 바로 __main__
이다.
즉, __name__
은 작동중인 모듈의 이름이 저장되는 변수에 불과하다.
따라서, 파이썬 인터프리터 입장에서는
"내가 지금 어디(어느 경로)에 있는지는 모르겠지만만
일단 지금 실행시키는 파일이
__main__
이라고 하더라" 라고 인식하는 것이다.
따라서,
if __name__ == '__main__':
인 경우에는 절대경로
를 지정해줘서 인터프리터가 다른 모듈 및 패키지를 참조할 수 있도록 해줘야 하는 것이다.
Q. add_and_multiply.py에서 multiply함수를 절대경로와 상대경로도 각각 임포트 해보고 main 모듈과 차이점을 생각해보고 결과를 출력해 보세요.
절대경로
from multiplication import multiply # from calculator.multiplication import multiply def add_and_multiply(a,b): return multiply(a,b) + (a+b) print(add_and_multiply(2,5))
main 모듈과 현재 add_and_multiply.py는 서로 연결되어 있지 않은 상태다.
add_and_multiply.py함수를 실행시키면 현재 이 파일이 __main__
이 된다.
따라서, 메인모듈에서 진행했던 이전 예제와 마찬가지로
절대경로로 지정해줘야 한다.
(참고) 그렇다면 왜 아래와 같이
절대경로
로 설정한 것 역시 에러가 출력될까
from calculator.multiplication import multiply
뭔가 문제다 싶으면 파일 경로를 자세히 봐야한다.
현제 내가 실행시키고 있는 파일은 add_and_multiply.py
인데,
calculator 폴더 안에 multiplication.py도 함께 있다.
즉, 같은 폴더 안에서의 절대경로 지정하기 위해서는 그 다음 하위 모듈을
기준으로 경로를 작성해야 한다.
Q.
__init__.py
파일의 역할
예시
mydir/spam/__init__.py
mydir/spam/module.py
위와 같은 경로가 있다.
__ìnit__.py
덕분에 파이썬은
mydir 디렉토리 안의 -> spam 디렉토리 안의 -> module.py까지 접근한다.
따라서
from spam import module
과 같은 방식으로 모듈을 import 할 수 있다.
- Import 할때 경로의 총 길이 줄여주기
- Package에서 import 할 수 있는 변수/함수/클래스 제한하기
- 그 외 package가 import될때 꼭 먼저 실행되어야 하는 코드들
예시
# __init__.py
from .mod1 import func2
# main.py
from pkg import func2
func2()
__init__.py
에서 경로 길이를 줄여주지 않았다면
import pkg.mod1
pkg.mod1.func2()
처럼 사용해야 한다.