[Python] 9. 모듈(Module)과 패키지(Package)

Wonder_Land🛕·2022년 6월 22일
0

[Python]

목록 보기
9/12
post-thumbnail
  1. 표준 모듈(Standard Module)과 활용
  2. 서드파티 모듈(Third Party Module) 설치 및 활용
  3. 사용자 정의 모듈(User Defined Module)
  4. 사용자 정의 패키지(User Defined Package)
  5. Q&A
  6. 마치며

우리가 프로그램을 개발할 때, 처음부터 끝까지 오로지 나만의 힘으로 짤 수 있을까요?

물론 그럴 수는 있겠지만, 어떻게보면 과한 욕심일 수도 있겠죠.

따라서 우리는 다른 사람들이 미리 개발한, 공개 코드를 사용할 수 있는데요.

이는 시행착오의 시간과 비용을 줄일 수 있는 현명한 방법이죠.


1. 표준 모듈(Standard Module)과 활용

  • 표준 모듈(Standard Module)
    : 각각의 목적에 맞게 설계되어 있고 다양한 함수나 클래스 등을 제공합니다.

    : 별도의 추가 설치 과정 없이 import()문으로 로딩해 사용할 수 있습니다.
import (모듈명)

1) 모듈 로딩

(1)import문과 모듈 로딩

다음은 표준 모듈인 math모듈을 사용한 예시입니다.

참고로 math 모듈은 각종 유용한 수학 함수와 미리 정의된 값들을 포함하고 있습니다.

import math

print(f"math.radians(90) = {math.radians(90)}")
print(f"math.pi = {math.pi}")

[Ruslt]
math.radians(90) = 1.5707963267948966
math.pi = 3.141592653589793

import math문을 통해 이름으로 math모듈이 가지는 함수나 클래스를 이용할 수 있습니다.


(2) import ~ as ~ 문과 모듈 별칭의 사용

길거나 복잡한 모듈명은 별칭을 사용하면
가독성도 좋아지고 더 편리하게 코딩할 수 있습니다.

import (모듈명) as (별칭)

다음은 math모듈을 별칭 m으로 참조하여 사용하는 예시입니다.

import math as m

print(f"m.radians(90) = {m.radians(90)}")	# 별칭 'm' 사용
print(f"m.pi = {m.pi}")	#별칭 'm' 사용

[Ruslt]
m.radians(90) = 1.5707963267948966
m.pi = 3.141592653589793


(3) from ~ import ~ 문을 이용한 선택적 로딩

모듈에서 필요한 함수나 클래스를 선택적으로도 이용할 수 있습니다.

from (모듈명) import

from ~ import * 문을 사용하면 모듈이나 패키지가 가지고 있는 함수, 값 등의 모든 정보를 로딩해서 사용할 수 있습니다.

아래의 예시를 볼까요?

from math import *
from math import radians, pi

print(f"radians(90) = {radians(90)}")
print(f"pi = {pi}")

[Ruslt]
radians(90) = 1.5707963267948966
pi = 3.141592653589793

from math import *을 통해 math 모듈이 가진 함수들을 직접 호출할 수 있습니다.

from math import radians, pi처럼 명시적으로 선언하면 선택적으로 함수와 값을 로딩해서 사용할 수도 있습니다.
이렇게 사용하면 math.pi처럼 로딩되지 않더라도
함수와 값이 직접 로딩됩니다.

이처럼 명시적으로 선언해 사용하면,
해당 함수가 어느 모듈에서 로딩되어 사용됐는지가 명확해지기 때문에,
명시적으로 사용함을 권장합니다.


2) sys 모듈

  • sys모듈
    : 시스템과 관련된 정보에 접근하거나, 명령행에서 전달된 명령행 매개변수로부터 인자값을 읽어올 때 사용됩니다.
import sys

print(f"sys.argv => {type(sys.argv)} {sys.argv}")

for i, val in enumerate(sys.argv):
    print(f"sys.argv[{i}] => {val}")

sys.argv는 list 타입으로, 명령행에서 python 명령에 전달된 인자들의 정보를 담고 있습니다.


3) random 모듈

  • random모듈
    : 난수(연속적인 임의의 수)를 생성하는 기능을 제공합니다.
from random import random, uniform, randrange, choice, choices, sample, shuffle

print(f"random() => {random()}")
print(f"uniform({1.0}), {10.0} => {uniform(1.0, 10.0)}")
print(f"randrange(0, 10, 2) => {randrange(0, 10, 2)}")

lst = [1, 2, 3, 4, 5]
print(f"choice {lst} => {choice(lst)}")
print(f"choices {lst} => {choices(lst, k = 2)}")
print(f"sample {lst} => {sample(lst, k = 2)}")

shuffle(lst)
print(f"shuffle {lst} => {lst}")

[Ruslt]
random() => 0.9069747739426011
uniform(1.0), 10.0 => 6.13377435173547
randrange(0, 10, 2) => 6
choice [1, 2, 3, 4, 5] => 3
choices [1, 2, 3, 4, 5] => [5, 5]
sample [1, 2, 3, 4, 5] => [4, 5]
shuffle [1, 4, 3, 2, 5] => [1, 4, 3, 2, 5]

  • random()함수 : 0.0 <= N < 1.0 범위의 부동소수점 난수 N을 생성합니다.

  • uniform()함수 : 지정된 범위 내의 부동소수점 난수 N을 생성합니다.

  • randrange()함수 : 지정된 범위의 정수형 난수 N을 생성합니다.
    (시작값 생략 시 0, 증감치 생략 시 1이 기본입니다.)

  • choice()함수 : 인자로 전달된 Sequence 객체의 항목 중 임의 항목을 반환합니다.

  • choices()함수 : 인자로 전달된 Sequence 객체의 항목 중 임의의 항목을 k개 반환합니다.
    (복원 추출 기능을 가진 시뮬레이션 함수입니다)
    ( == 동일한 항목을 고를 수 있습니다.)

  • sample()함수 : 인자로 전달된 Sequence 객체, 혹은 Set 객체 항목 중 임의의 항목을 k개 반환합니다.
    (비복원추출 기능을 가진 시뮬레이션 함수입니다.)
    ( == 동일한 항목을 고를 수 없습니다.)

  • shuffle()함수 : 인자로 전달된 Sequence 객체의 항목을 뒤섞는 함수입니다.
    (반환값은 없으며, 원본 객체의 항목 순서를 뒤섞습니다.)


4) datetime 모듈

  • datetime모듈
    : 날짜와 시간 정보를 확인하고 조작하는 클래스, 함수 등을 제공합니다.
from datetime import datetime, timezone, timedelta

now = datetime.now()
print(f"{now.year}-{now.month:02}-{now.day:02}")
print(f"{now.hour:02}:{now.minute:02}:{now.second:02}")

fmt = "%Y{0} %m{1} %d{2} %H{3} %M{4} %S{5}"
print(now.strftime(fmt).format(*"년월일시분초"))

[Ruslt]
2022-06-22
15:22:54
2022년 06월 22일 15시 22분 54초

"%Y{0} %m{1} %d{2} %H{3} %M{4} %S{5}"에서

  • %Y : 네 자리의 연도 정보
  • %m : 월 정보
  • %d : 일 정보
  • %H: 24시간 체계의 시간 정보
  • %M : 분 정보
  • %S : 초 정보
    를 표현합니다.

2. 서드파티 모듈(Third Party Module) 설치 및 활용

Python은 다양한 표준 모듈(Standard Module)을 제공합니다.

하지만 표준 모듈이 모든 목적에 부합하는 것은 아니며,
모든 기능을 제공하는 것 역시 아닙니다.

하지만 Python은 다른 사람에게서 만들어진 모듈을 공유하는 시스템이 굉장히 활성화되어 있습니다.

따라서 내가 만든 모듈을 공유하거나, 다른 사람이 만든 모듈을 사용할 수 있습니다.

Python은 설치 시, 기본적으로 'PIP'라는 도구를 함께 설치합니다.

'PIP'도구를 통해, Third Party Module을 설치하거나 제거할 수 있습니다.

  • 서드파티 모듈(Third Party Module)
    : 다른 사람에 의해 만들어져 배포되고 공유되는 모듈
    (외부 모듈(External Module)이라고도 합니다.)
pip install (모듈명)	    # 서드파티 설치
pip uninstall (모듈명)	# 서드파티 제거

3. 사용자 정의 모듈(User Defined Module)

Python에서 모듈은 파일 단위로 관리됩니다.

따라서, 파일명은 모듈의 이름이 됩니다.
ex) 'Test.py'는 하나의 모듈이며, 이 모듈의 이름은 'Test'입니다.

모듈은
1) 실행의 목적(Python 명령에 의해 실행)
2) 라이브러리의 목적(import문에 의해 로딩)
을 가집니다.

다음은 라이브러리로 사용할 목적의 모듈입니다.

# Calc1.py #

def plus(x, y):
    return x + y

def minus(x, y):
    return x - y
# Calc2.py #

def multiply(x, y):
    return x * y

def divide(x, y):
    return x / y

다음은 라이브러리 모듈을 사용하기 위한 실행 모듈입니다.

import Calc1, Calc2

op1, op2 = 2, 3

print(f'plus({op1}, {op2}) => {Calc1.plus(op1, op2)}')
print(f'minus({op1}, {op2}) => {Calc1.minus(op1, op2)}')
print(f'multiply({op1}, {op2}) => {Calc2.multiply(op1, op2)}')
print(f'divide({op1}, {op2}) => {Calc2.divide(op1, op2)}')

[Result]
plus(2, 3) => 5
minus(2, 3) => -1
multiply(2, 3) => 6
divide(2, 3) => 0.6666666666666666


(1) 모듈의 __name__ 속성

  • 실행 목적의 모듈의 __name__ 속성
    : "__main__" 문자열의 값이 들어가 있습니다.

  • 라이브러리 목적의 모듈의 __name__ 속성
    : 모듈의 이름이 저장되어 있습니다.

# myCalc1.py #

def plus(x, y):
    return x + y

def minus(x, y):
    return x - y

if __name__ == "__main__":
    print(f"plus(3, 2) => {plus(3, 2)}")
    print(f"minus(3, 2) => {minus(3, 2)}")

if __name__ == "__main__":을 통해
main 모듈을 실행하지 않고, python 명령으로 직접 실행하면
__name__속성에 "__main__" 문자열의 값이 저장됩니다.

즉, 모듈로 실행되었을 때와, 메인으로 실행되었을 떄를 구분해 동작할 수 있습니다.


4. 사용자 정의 패키지(User Defined Package)

Module이 모여 폴더를 구성하면 Package를 만들 수 있습니다.

패키지를 정의하고, 모듈을 포함해 사용하는 방법에 대해 알아보겠습니다.

(1) 패키지 정의

1) 폴더 생성

패키지를 구성하기 위해서는 먼저 폴더가 생성되어야 합니다.

먼저 Calc라는 폴더를 생성하고,
해당 폴더에
1)
2) myCalc1.py
3) myCalc2.py
를 넣습니다.

__init__.py 파일에는

__all__ = ["myCalc1", "myCalc2"]

print("package Calc를 로딩하였습니다.")

를 작성합니다.

__all__ 속성에 패키지에 포함될 모듈 이름을 저장 시켜줍니다.
그리고 패키지 로딩 확인을 위한 출력 메시지도 작성해줍니다.

(2) 패키지 사용

from (패키지명) import (모듈명)

(모듈명)생략하면, 해당 패키지의 모든 모듈을 로딩하고,
(모듈명)지정하면, 선택적으로 모듈을 로딩할 수 있습니다.

from Calc import myCalc1, myCalc2	# 선택적 모듈 로딩
# from Calc import  # 모든 모듈 로딩

op1, op2 = 2, 3

print(f"plus({op1}, {op2}) => {myCalc1.plus(op1, op2)}")
print(f"minus({op1}, {op2}) => {myCalc1.minus(op1, op2)}")
print(f"multiply({op1}, {op2}) => {myCalc2.multiply(op1, op2)}")
print(f"divide({op1}, {op2}) => {myCalc2.divide(op1, op2)}")

[Result]
package Calc를 로딩하였습니다.
plus(2, 3) => 5
minus(2, 3) => -1
multiply(2, 3) => 6
divide(2, 3) => 0.6666666666666666


5. Q&A

-


6. 마치며

사실 혼자 공부하는 입장에서, 모듈이나 패키지를 활용하는 경우는 거의 없었습니다...

그래서 그런지 배우기는 해도 별 다른 중요성을 느끼지 못했고, 사용하지도 않았던 것 같네요..

하지만, 코드를 짤 때 용이성이나 효율성을 생각하면 사용하는게 더 권장되기는 하죠..

앞으로 계속 써보면서 익숙해져야겠습니다 😊

[Reference] : 위 글은 다음 내용을 참고, 인용하여 만들어졌습니다.

  • 전반적 내용 : 삼성 SW Expert Academy
profile
아무것도 모르는 컴공 학생의 Wonder_Land

0개의 댓글