PY | 모듈(module)과 패키지(package)

Stellar·2021년 5월 23일
0

Python

목록 보기
10/36
post-thumbnail
post-custom-banner

모듈과 패키지란?

input, print 등의 내장 함수만으로는 복잡한 코드를 짜기엔 한계가 있어 파이썬의 random, turtle, pickle 등의 모듈과 패키지를 사용해야함.
import abc # abc가 모듈 또는 패키지

파일 이름과 import 되는 모듈명이 같을 경우 에러가 발생한다.

✔️ 모듈, 패키지, 라이브러리

  • 모듈(module)

    • 각종 변수, 함수, 클래스를 담고있는 파일
    • 특정 기능을 .py파일 단위로 작성한 것
  • 패키지(package)

    • 여러 모듈을 묶은 것
    • 특정 기능과 관련된 여러 모듈을 묶은 것.
    • 패키지는 네임스페이스(namespace, 이름공간)를 제공
  • 파이썬 표준 라이브러리

    • 파이썬에 기본으로 설치괸 모듈과 패키지, 내장 함수를 묶어서 파이썬 표준 라이브러리(Python Standard Library, PSL)이라 부름

1. Module

함수들이 뭉쳐진 하나의 .py 파일 안에 이루어진 것을 모듈이라 함.
즉 하나의 파일이 모듈이다.
참고. 한 권으로 끝내는 <파이썬 노트> 패키지와 모듈

✔️ 모듈 import

모듈(파일)에서 함수의 이름만 import 해주면 짧은 코드 작성이 가능하다.

import sys
sys.path.append('C:/PyStudy')

#import mypack.calc.add
#mypack.calc.add.outadd(1, 2)

#코드 단순화
#from mypack.calc import add
#add.outadd(1, 2)

#함수의 이름만 import
from mypack.calc.add import outadd
outadd(1, 2)

2. Package

여러 개의 모듈을 그룹화 하면 패키지가 됨. 디렉토리는 패키지로 정의 됨.
패키지는 종종 라이브러리라고도 불린다.
그룹화를 통한 쉬운 관리를 위해 패키지 사용을 권장한다.

✔️ import * 이라고 모든 모듈을 import 할 수 없다.

모듈을 다 읽어 오려면 엄청난 시간이 걸리므로 불러올 모듈을 별도로 설정해야 함.

디렉토리는 같은 위치인 경우를 기준.

  • 모듈 지정 파일 __init__.py

    파일명은 ___init__로 생성해야 함.

__all__ = ['add', 'multi']
print('add module imported')
  • 실행 파일
#usepackage
import sys
sys.path.append('C:/PyStudy')

from mypack.calc import *
add.outadd(1, 2)
multi.outmulti(2, 3)

파이썬이 module과 package 검색하는 방법

✔️ Import search 순서

  1. sys.modules
    • 파일을 찾기 위해 가장 먼저 확인
    • 단순한 dict 타입이다
    • 이미 import된 모듈과 패키지를 저장하고 있어 python이 다시 찾지 않아도 되는 기능
    • 새로 import할 경우 찾지 못한다.
  2. bulit-in modules
    • sys.modules 다음으로 확인
    • 파이썬 기본 제공하는 공식 라이브러리
  3. sys.path
    • str 요소를 가진 list이다 (경로 표시 ./../)
    • 파이썬에 포함된 모듈
    • sys 모듈을 import해서 sys.modulessys.path 출력 및 수정 가능
    • sys.path 에서도 못찾으면 ModuleNotFoundError 에러를 리턴한다.

모듈 종류

SYS

sys, 시스템 정보를 알아보자.

import sys

print('버전 : ', sys.version)
print('플랫폼 : ', sys.platform)

if sys.platform == 'win32' :
    print(sys.getwindowsversion())

print('바이트 순서 : ', sys.byteorder)
print('모듈 경로 : ', sys.path)
sys.exit(0)

현재 파일의 위치 경로를 불러옴.

import sys

print(sys.argv)

sys.modulessys.path의 차이점

sys.modules를 우선적으로 찾은 뒤 sys.path를 마지막으로 확인하는데 이때 sys.path에서도 못찾으면 ModuleNotFoundError 에러가 난다.

파이썬이 sys 모듈의 위치를 찾는법

sysimport 해야하는 모듈이기 때문에 파이썬이 찾아야하는데 sys의 경우 bulit-in module이라서 2번째 순서로 검색 후 찾은 다음import 할 수 있다.

Absolute pathrelative path의 차이점을 서술해 주세요.

  • Absolute path는 이름 그대로 절대 경로이다. 프로젝트 내에서는 어느 파일, 어느 위치에서 import를 하는 파일이나 경로에 상관없이 항상 경로가 동일하기 때문
  • absolute path를 사용하게 되면 경로가 길어질 수 있어 이러한 단점을 보완하기 위해서 relative path를 사용할 수 있다.
  • Relative pathabsolute path와 다르게 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡는게 아니라 import 하는 위치를 기준으로 경로를 정의해서 일반적으로 relative path는 local package 안에서 다른 local package를 import 할때 사용
  • Relative path는 선언해야 하는 경로의 길이를 줄여준다는 장점은 있지만 헷갈리기 쉽고 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점이 있어 웬만한 경우 absolute path를 사용

✔️ calculator 패키지 만들기 연습

main.py

# absoulte path
# from calculator.add_and_multiply import add_and_multiply 

# relative path
from .calculator.add_and_multiply import add_and_multiply

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

add_and_multiply.py

from .multiplication import multiply
# from calculator.multiplication import multiply

def add_and_multiply(a,b):
    return multiply(a,b) + (a+b)

multiplication.py

def multiply(a,b):
    return(a*b)

4-1. main.py에서 상대경로로 add_and_mutiply 를 임포트 했을 때 에러 발생

main.py

# absoulte path
# from calculator.add_and_multiply import add_and_multiply 

# relative path
from .calculator.add_and_multiply import add_and_multiply

if __name__ == '__main__':
    print(add_and_multiply(1,2))
# ImportError 발생
Traceback (most recent call last):
  File "/home/hwang/dev/python/calculator_pratice/main.py", line 4, in <module>
    from .calculator.add_and_multiply import add_and_multiply
ImportError: attempted relative import with no known parent package

__main__으로 사용할 파일은 항상 absolute path로 지정해줘야 한다.
__main__이란❓️ 처음 실행하는 소스 파일이 메인 모듈이다.

main.py

# absoulte path
from calculator.add_and_multiply import add_and_multiply 

# relative path
# from .calculator.add_and_multiply import add_and_multiply

if __name__ == '__main__':
    print(add_and_multiply(1,2))
=========================================================
/home/hwang/dev/python/calculator_pratice/main.py
5

4-2. add_and_multiply.py에서 multiply함수를 상대경로로 임포트 해보기

add_and_multiply.py : relative path일때

# relative path
from .multiplication import multiply
# from calculator.multiplication import multiply

def add_and_multiply(a,b):
    return multiply(a,b) + (a+b)
=========================================================
# ImportError 발생
Traceback (most recent call last):
  File "/home/hwang/dev/python/calculator_pratice/calculator/add_and_multiply.py", line 1, in <module>
    from .multiplication import multiply
ImportError: attempted relative import with no known parent package
  • 발생한 에러

    • ImportError: attempted relative import with no known parent package
  • 에러가 발생한 이유

    • import 하는 위치를 기준으로 경로를 정의하기 때문에 add_and_multiply.py 파일의 부모 경로가 multiplication.py로 잡혀있어 에러가 발생함
  • 해결 방법

    • 절대 경로를 지정하면 된다 (아래 코드 참고)

참고한 사이트


4-3. add_and_multiply.py에서 multiply함수를 절대경로로 임포트 해보기

add_and_multiply.py : absolute path일때

# from .multiplication import multiply
# absolute path
from calculator.multiplication import multiply

def add_and_multiply(a,b):
    return multiply(a,b) + (a+b)
=========================================================
# ModuleNotFoundError 발생
Traceback (most recent call last):
  File "/home/hwang/dev/python/calculator_pratice/calculator/add_and_multiply.py", line 2, in <module>
    from calculator.multiplication import multiply
ModuleNotFoundError: No module named 'calculator'
  • 발생한 에러
    • ModuleNotFoundError: No module named 'calculator'
  • 에러가 발생한 이유
    • add_and_multiply.py 파일을 실행 시켰을 경우 메인 파일이 된다. 파이썬 공식 문서에도 적혀있듯이 메인 파일은 절대경로를 사용해야함.
  • 해결 방법
    • add_and_multiply.py파일에 import할 파일 multiplication.py가 동일한 위치에 있기 때문에 파일 명만 적어주면 add_and_multiply.py 파일을 실행했을때 정상적으로 작동한다.

      (add_and_multiply.pymultiplication.py이 같은 위치에 있음)

add_and_multiply.py

# from .multiplication import multiply
from multiplication import multiply # 절대경로


def add_and_multiply(a, b):
    return multiply(a, b) + (a+b)


print(add_and_multiply(4, 10))
=================================================
> 54

참고한 사이트

suasue.log

✔️ __init__.py 파일의 역할

  1. __init__.py 파일에는 아무코드도 없지만 init 파일은 해당 디렉토리가 패키지임을 알려주는 역할을 한다.
  2. python 3.3 버전부터는 init.py 파일이 없어도 패키지로 인식된다
  3. 하위 버전 호환을 위해 init.py 파일을 생성하는 것이 안전한 방법
post-custom-banner

0개의 댓글