[8일차] 모듈

2022. 12. 29. 16:51데이터 엔지니어링 과정/python

목차
1. 모듈을 사용하는 이유
2. 모듈 생성 및 호출
3. 모듈을 직접 실행하는 경우와 임포트한 후 실행하는 경우 구분하기
4. 내장 모듈
5. 패키지

 

1. 모듈을 사용하는 이유

1. 모듈

: 상수, 변수 함수, 클래스를 포함하는 코드가 저장된 파일

2. 모듈을 사용하는 이유

  • 모듈로 나누면 코드 작성과 관리가 편해짐
  • 이미 작성된 코드 재사용 가능
  • 공동 작업이 편리해짐

 

2. 모듈 생성 및 호출

0. 파일 처리 관련

  • 주피터 노트북에서 사용할 수 있는 IPython의 내장 마술 명령어 이용
  • %%writefile [-a] file.py 코드 셀의 코드를 파이썬 코드 파일로 저장
    [-a] 옵션을 사용하지 않을 경우, 같은 파일의 이름이 있으면 덮어씀. 있을 경우 뒤에 추가
  • %load file.py 저장된 파이썬 코드 불러오기
    지정된 코드 파일 ('file.py')을 읽어서 코드 셀에 표시
  • %run file.py 파이썬 코드 파일 실행하기
    지정된 파이썬 코드 파일 (file.py)을 실행함

1. 모듈 만들기

%%writefile C:\myPyCode\my_first_module.py
# File name: my_first_module.py

def my_function():
    print("This is my first module")
    
>>> Writing C:\myPyCode\my_first_module.py   

# 다시 실행한다면 이렇게 보임
>>> Overwriting C:\myPyCode\my_first_module.py

👀 type 이용해서 파일 잘 생성됐는지 확인해보기

!type C:\myPyCode\my_first_module.py

# File name: my_first_module.py

def my_function():
    print("This is my first module")

2. 모듈 불러오기

  • cd C:\myPyCode 폴더로 이동해서 사용하기
  • import 모듈명 모듈 부르기
import my_first_module

my_first_module.my_function()
>>> This is my first module
  • 환경 변수 설정 확인
!echo %PYTHONPATH%
>>> C:\myPyCode\modules;C:\myPyCode\packages
#새로운 모듈 작성

%%writefile C:\myPyCode\modules\my_area.py
#File mane: my_area.py

PI = 3.14
def square_area(a): # 정사각형의 넓이 반환
    return a **2

def circle_area(r): # 원의 넓이 반환
    return PI * r **2

>>> Writing C:\myPyCode\modules\my_area.py
  • 다른 폴더에서 모듈 불러오기
cd C:\myPyCode

import my_area # 모듈 불러오기

print ('pi = ', my_area.PI) #모듈의 변수 이용
print('square area = ', my_area.square_area(5)) #모듈의 함수 이용
print('circle area = ', my_area.circle_area(2)) 

>>> pi =  3.14
>>> square area =  25
>>> circle area =  12.56
  • 불러온 모듈에서 사용할 수 있는 변수, 함수, 클래스를 알고 싶은 경우 dir(모듈명) 사용
dir (my_area)
>>> ['PI',
 '__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 'circle_area',
 'square_area']

3. 모듈을 불러오는 다른 형식

  • 모듈의 내용 바로 선언

#모듈의 변수 바로 불러오기
from my_area import PI 

print('pi =',PI) #모듈의 변수 이용
>>> pi = 3.14


#모듈의 함수 바로 불러오기
from my_area import square_area 
from my_area import circle_area

print('square area =', square_area(5)) #모듈의 함수 이용
print('circle area =', circle_area(2))
>>> square area = 25
>>> circle area = 12.56


#여러 개 동시 선언은 ,(콤마)로 구분하여 사용 가능
from my_area import PI, square_area, circle_area

print('pi =',PI) #모듈의 변수 이용
print('square area =', square_area(5)) #모듈의 함수 이용
print('circle area =', circle_area(2))
>>> pi = 3.14
>>> square area = 25
>>> circle area = 12.56
# 모듈의 모든 변수, 함수, 클래스를 모듈명없이 바로 사용하고 싶은 경우 * 사용

from my_area import *

print('pi =',PI) #모듈의 변수 이용
print('square area =', square_area(5)) #모듈의 함수 이용
print('circle area =', circle_area(2))
>>> pi = 3.14
>>> square area = 25
>>> circle area = 12.56

👀 여러 모듈 사용 시 주의사항 ➡ 두 개 이상의 모듈을 쓸 때 주의가 필요

먼저 2개의 모듈을 제작한다. 여기서 func2는 두 모듈이 각각 따로 가지고 있도록 한다.

#첫 번째 모듈 my_moduel1
%%writefile C:\myPyCode\modules\my_module1.py
#File name: my_module1.py

def func1():
    print("func1 in my_module1 ")
def func2():
    print("func2 in my module1 ")
    
    
#두번째 모듈 my_moduel2    
%%writefile C:\myPyCode\modules\my_module2.py
#File name: my_module2.py

def func2():
    print("func2 in my_module2 ")
def func3():
    print("func3 in my module2 ")

여기서 import *을 통해 각 모듈의 전체 함수를 불러본다면?!

from my_module1 import *
from my_module2 import *

func1()
func2()
func3()

>>> func1 in my_module1 
>>> func2 in my_module2 
>>> func3 in my module2

func2를 둘 다 가지고 있다보니, 마지막에 등록된 my_module2의 func2가 적용되었음을 확인할 수 있다.

만약 my_module2를 먼저 부른다면?

from my_module2 import *
from my_module1 import *

func1()
func2()
func3()

>>> func1 in my_module1 
>>> func2 in my module1 
>>> func3 in my module2

func2가 이번엔 my_module1의 함수로 받았다. 

이렇듯, 다른 모듈에서 이름이 같은 함수명을 가지고 있을 때 import * 을 한다면, 마지막에 불러들인 모듈의 함수를 가져오면서 의도와 다른 결과를 불러올 수 있기 때문에 주의해야 한다.

  • import 모듈명 as 별명 모듈명을 별명으로 선언
import my_area as area #모듈명(my)area에 별명(area)을 붙임

print('pi =',area.PI) #모듈명 대신 별명 이용
print('square area =', area.square_area(5)) 
print('circle area =', area.circle_area(2))

>>> pi = 3.14
>>> square area = 25
>>> circle area = 12.56

👀 모듈뿐만 아니라 변수,함수도 별명으로 부를 수 있다!

from my_area import PI as pi
from my_area import square_area as square
from my_area import circle_area as circle

print('pi =',pi) #모듈 변수의 별명 이용
print('square area =', square(5)) #모듈 함수의 별명 이용
print('circle area =', circle(2))

>>> pi = 3.14
>>> square area = 25
>>> circle area = 12.56

 

3. 모듈을 직접 실행하는 경우와 임포트한 후 실행하는 경우 구분하기

1. 모듈 제작 후, 모듈 속 함수가 잘 작성됐는지 확인하기

  • my_module_test1 모듈 만들기
%%writefile C:\myPyCode\modules\my_module_test1.py
# File name: my_modlue_test1.py

def func(a):
    print("입력 숫자:",a)
    
func(3)
  • 주피터 노트북 속 내장 마술 명령어를 통해 모듈 실행하기
%run C:\myPyCode\modules\my_module_test1.py

>>> 입력 숫자: 3
  • 임포트해서 사용하기
import my_module_test1

>>> 입력 숫자: 3

2. 직접 실행하는 경우와 import해서 실행하는 경우 다르게 결과 도출

(1) if __name__ == "main": 직접 수행할 때만 실행되는 코드 (import시 실행 X)

  • if__name__ == "main" 를 가진 my_module_test2 만들기
%%writefile C:\myPyCode\modules\my_module_test2.py
# File name: my_modlue_test2.py

def func(a):
    print("입력 숫자:",a)
    
if __name__ == "__main__": # 직접 수행 할 때만 실행되는 코드
    print("모듈을 직접 실행")
    func(3)
    func(4)
  • 주피터 노트북 속 내장 마술 명령어를 통해 모듈 실행하기
%run C:\myPyCode\modules\my_module_test2.py

>>> 모듈을 직접 실행
>>> 입력 숫자: 3
>>> 입력 숫자: 4
  • 임포트해서 사용하기
import my_module_test2

➡실행되지 않는다!

(2) 모듈에서 코드 직접 수행할 때와 임포트해서 사용할 때 결과 차이나게 하기

  • if__name__ == "main" 과 else: 를 가진 my_module_test3 만들기
%%writefile C:\myPyCode\modules\my_module_test3.py
# File name: my_modlue_test3.py

def func(a):
    print("입력 숫자:",a)
    
if __name__ == "__main__": # 직접 수행 할 때만 실행되는 코드
    print("모듈을 직접 실행")
    func(3)
    func(4)
else:
    print("모듈을 임포트해서 실행")
  • 주피터 노트북 속 내장 마술 명령어를 통해 모듈 실행하기
%run C:\myPyCode\modules\my_module_test3.py

>>> 모듈을 직접 실행
>>> 입력 숫자: 3
>>> 입력 숫자: 4
  • 임포트해서 사용하기
import my_module_test3

>>> 모듈을 임포트해서 실행

 

4. 내장 모듈

1. 난수 발생 모듈

  • random()
    0.0~1.0 범위의 임의의 실수 반환
import random 

random.random()
>>> 0.7956675997054554
  • randint(a,b)
    a <= 정수 <= b 범위의 임의의 정수 반환
import random

dice1 = random.randint(1,6) #임의의 정수가 생성됨
dice2 = random.randint(1,6) #임의의 정수가 생성됨

print('주사위 두 개의 숫자: {0}, {1}'.format(dice1,dice2))
>>> 주사위 두 개의 숫자: 4, 5
  • randrange([start,] stop [,step])
    randrange([start,] stop [,step])에서 임의의 정수를 반환
import random

num1 = random.randrange(1,10,2) # 1 ~ 9(10-1) 중 임의의 홀수 선택
num2 = random.randrange(0,100,10) # 0 ~ 99(100-1) 중 임의의 10 단위 숫자 선택

print('num1: {0}, num2:{1}'.format(num1,num2))
>>> num1: 9, num2:20
  • chioce(seq)
    공백이 아닌 시퀀스(seq)에서 임의의 항목을 반환
import random

menu = ['비빔밥', '된장찌개', '볶음밥', '불고기', '스파게티', '피자', '탕수육']

random.choice(menu)
>>> '된장찌개'
  • sample(population,k)
    시퀀스로 이뤄진 모집단(population)에서 중복되지 않는 k개의 인자를 반환
import random

random.sample([1,2,3,4,5],2) #모집단에서 두 개의 인자 선택
>>> [1, 4]

2. 날짜 및 시간 관련 처리 모듈

  • datatime.date 예시
import datetime

set_day = datetime.date(2022,12,28)

print(set_day)
>>> 2022-12-28

print("{0}/{1}/{2}".format(set_day.year,set_day.month, set_day.day))
>>> 2022/12/28
  • 날짜 계산하기
import datetime

day1 = datetime.date(2019, 4, 1)
day2 = datetime.date(2019, 7, 10)
diff_day = day2 - day1

print(diff_day)
>>> 100 days, 0:00:00

type(day1)
>>> datetime.date

type(diff_day)
>>> datetime.timedelta

print("** 지정된 두 날짜의 차이는 {}일입니다. **".format(diff_day.days))
>>> ** 지정된 두 날짜의 차이는 100일입니다. **

👀 연산을 한 diff_day의 type은 timedelta가 되었다!

  • today() 오늘 날짜 반환하는 클래스 메서드
import datetime

print(datetime.date.today())
>>> 2022-12-29
  • 오늘과 특정 날짜의 차이 구하기
import datetime

today = datetime.date.today()
special_day = datetime.date(2018,12,31)

print(special_day - today)
>>> -1459 days, 0:00:00
  • 시간과 관련된 처리를 할 수 있는 time 클래스
import datetime

set_time = datetime.time(15, 30, 45)

print(set_time)
>>> 15:30:45

print("{0}/{1}/{2}".format(set_time.hour,set_time.minute, set_time.second))
>>> 15/30/45

set_dt = datetime.datetime(2018,10,9,10,20,0) # 모듈 datetime과 클래스 datetime
print(set_dt)
>>> 2018-10-09 10:20:00

print("날짜 {0}/{1}/{2}".format(set_dt.year,set_dt.month, set_dt.day))
print("시간 {0}:{1}:{2}".format(set_dt.hour,set_dt.minute, set_dt.second))
>>> 날짜 2018/10/9
>>> 시간 10:20:0
  • 현재 날짜와 시간 불러오기
import datetime

now = datetime.datetime.now()
print(now)
>>> 2022-12-29 14:28:12.054805

👀 양식 지정해서 출력도 가능하다 {: }

print("Date & Time: {:%Y-%m-%d, %H:%M:%S}".format(now))
>>> Date & Time: 2022-12-29, 14:28:12

print("Date: {:%Y, %m, %d}".format(now))
print("Time: {:%H/%M/%S}".format(now))
>>> Date: 2022, 12, 29
>>> Time: 14/28/12
  • datetime 클래스 객체의 빼기 연산
now=datetime.datetime.now()
set_dt = datetime.datetime(2020,12,1,12,30,45)

print("현재 날짜 및 시각:", now)
print("차이:", set_dt-now)
>>> 현재 날짜 및 시각: 2022-12-29 14:40:02.181577
>>> 차이: -759 days, 21:50:42.818423
  • 모듈명 없이 사용하기
from datetime import date, time, datetime

print(date(2019, 7, 1))
>>> 2019-07-01

print(date.today())
>>> 2022-12-29

print(time(15,30,45))
>>> 15:30:45 

print(datetime(2020,2,14,18,10,50))
>>> 2020-02-14 18:10:50

print(datetime(2020, 2, 14, 18, 10,50))
>>> 2020-02-14 18:10:50

print(datetime.now())
>>> 2022-12-29 14:41:27.368350

3. 달력 생성 및 처리 모듈

  • calender(year [,3]) 지정된 연도 (year)의 전체 달력을 문자열로 반환 (기본 3개월)
import calendar

print(calendar.calendar(2023))

print(calendar.calendar(2023, m=4))

  • month(year, month) 지정된 연도(year)과 월(month)을 문자열로 반환
print(calendar.month(2020,9))

  • monthrange(year,month) 지정된 연도(year)와 월(month)의 시작 요일과 일수 반환.
    요일의 경우 0(월요일)~6(일요일)사이의 숫자로 반환
calendar.monthrange(2023,4)
>>> (5, 30)
  • firstweekday() 일주일의 시작요일 구하기
calendar.firstweekday()
>>> 0
  • setfirstweekday(weekday) 달력에 표시되는 첫번째 요일 지정한다.
calendar.setfirstweekday(calendar.SUNDAY)
print(calendar.month(2023,4))

  • weekday(year,month,day) 해당 날짜의 요일 반환
print(calendar.weekday(2022, 12, 29))
>>> 3
  • isleap(year) 지정 된 년(year)도가 윤년인지 알아보기
print(calendar.isleap(2018))
print(calendar.isleap(2020))

>>> False
>>> True

 

5. 패키지

1. 패키지의 구조

  • 여러 개의 모듈을 체계적으로 모아둔 구조
  • 폴더 구조로 되어 있으며, 각 폴더 안에 파일과 모듈들이 저장되어 있다.

2. 패키지 만들기

  • 폴더 만들기
mkdir C:\myPyCode\packages\image; C:\myPyCode\packages\image\io_file
  • 각각의 폴더에 모듈 생성
%%writefile C:\myPyCode\packages\image\__init__.py
# File name: __init__.py

>>> Writing C:\myPyCode\packages\image\__init__.py



%%writefile C:\myPyCode\packages\image\io_file\__init__.py
# File name: __init__.py

>>> Writing C:\myPyCode\packages\image\io_file\__init__.py



%%writefile C:\myPyCode\packages\image\io_file\imgread.py
# File name: imgread.py

def pngread():
    print("pngread in imgread module")
    
def jpgread():
    print("jpgread in imgread module")

>>> Writing C:\myPyCode\packages\image\io_file\imgread.py
  • 생성확인명령
    tree 폴더의 구조 표시
    tree /F 파일까지 표시
!tree /F c:\myPyCode\packages


폴더 PATH의 목록입니다.
볼륨 일련 번호가 000000A8 64D5:C191입니다.
C:\MYPYCODE\PACKAGES
└─image
    │  __init__.py
    │  
    └─io_file
            imgread.py
            __init__.py

3. 패키지 사용하기

(1) 사용 방법
      
import 패키지명.모듈명

      import 패키지명.폴더명.모듈명

import image.io_file.imgread # image 패키지 io_file 폴더의 imgread 모듈 임포트

image.io_file.imgread.pngread() # imgraed 모듈 내의 pngread() 함수 호출
image.io_file.imgread.jpgread() # imgread 모듈 내의 jpgread() 함수 호출

>>> pngread in imgread module
>>> jpgread in imgread module

(2) from A import B로 간단하게 사용하기

from image.io_file import imgread

imgread.pngread()
imgread.jpgread()

>>> pngread in imgread module
>>> jpgread in imgread module

(2) 함수명을 B에 입력하여 더 간단하게 사용하기

from image.io_file.imgread import pngread

pngread()

>>> pngread in imgread module

(3) 모듈의 모든 함수 부르기 * 사용

from image.io_file.imgread import *

pngread()
jpgread()

>>> pngread in imgread module
>>> jpgread in imgread module

(4) 필요한 함수만 쓰기

from image.io_file.imgread import pngread, jpgread

pngread()
jpgread()

>>> pngread in imgread module
>>> jpgread in imgread module

(5) 별명 만들기 as 별명

from image.io_file.imgread import pngread as pread
from image.io_file.imgread import jpgread as jread

pread()
jread()

>>> pngread in imgread module
>>> jpgread in imgread module