[Python] 모듈 (Module), 패키지(Package), 라이브러리(Library)

is Yoon·2023년 8월 20일
0

Python

목록 보기
14/17

모듈 Module

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

  • 모듈로 나누면 코드 작성과 관리가 쉬워진다.
    기능별로 여러 파일에서 해당 기능의 코드를 구현하면, 하나의 코드 파일에서는 해당 기능의 구현에만 신경쓰면 된다.
  • 이미 작성된 코드를 재사용할 수 있다.
    예전에 만들었던 모듈이나 다른 사람이 만든 모듈도 사용할 수 있다.
  • 공동 작업이 편리해진다.
    프로그램을 모듈별로 설계하고 개인별로 나누어 코딩한 후 전체 모듈을 통합하여 공동 작업으로 인한 복잡성이 줄고 효율이 높아진다.

스크립트
프로그램을 작동시키는 코드를 담은 실행 용도의 파일
스크립트로 실행, 모듈은 코드 저장




모듈 만들기

  • 모듈 이름.py로 저장
  • 주피터에서 사용할 수 있는 마술 명령어 %%writefile 이용
%%writefile character.py
class Character :
	def __init__(self, name, health) :
    	self.name = name
    	self.health = health
    
    def attack(self) :
	    print(f"{self.name}이(가) 공격합니다!")
  • %%writefile [-a] (경로)파일이름.py - 기존 파일의 내용 뒤에 추가하기
  • %load 파일이름.py - 파일의 코드를 읽어서 코드 셀에 표시하기
  • %run 파일이름.py - 파일 실행하기



모듈 불러오기

1) 단일 모듈 불러오기

  • import 모듈명 : 모든 모듈 내용 불러옴
  • 모듈명.변수(), 모듈명.함수() 형태로 모듈 내의 변수, 함수 호출 가능
import character
character.attack()    # 모듈명.함수() -> 모듈의 함수 실행

2) 특정 내용만 불러오기

  • from 모듈명 import 변수명
  • from 모듈명 import 함수명
  • from 모듈명 import 클래스명
  • from 모듈명 import * - 모듈 내의 모든 변수, 함수, 클래스 불러오기 (여러 모듈을 동시에 이용할 때에는 주의 요망)
from character import attack

3) 모듈에 별칭 지정하기

  • import 모듈명 as 별명
  • from 모듈명 import 변수명/함수명/클래스명 as 별명
from character import attack as a
print(a)

4) 모듈 확인하기

  • dir(모듈명) : 파일의 네임스페이스 호출
  • 네임 스페이스 : 파일에서 정의된 모든 이름들
import module
print(dir(module))

5) 모듈 검색 경로

import sys
print(sys.path)

sys.path에 .append()로 새로운 경로를 직접 추가할 수 있다. sys.path = list

import sys
sys.path.append('/Users/codeit/Desktop')      # macOS
sys.path.append('C:\\Users\\codeit\\Desktop') # Windows

위의 방법은 프로그램이 종료되면 그 경로는 sys.path에서 사라진다.
sys.path에 영구적으로 경로 추가할 수도 있다.

  • PyCharm 설정 (Windows: File → Settings, macOS: PyCharm → Preferences) > Project 탭 > Project Interpreter 클릭
  • 톱니바퀴 버튼 > Show All 옵션 클릭
  • 파일 경로 아이콘 클릭 > + 아이콘 > 원하는 경로를 추가 > OK




name 특수 변수

  • __name__ : 모듈의 이름을 저장해 놓은 변수 (값 = 파이썬 자동)

모듈 직접 실행 or 임포트한 후 실행

  • 파일을 직접 실행하면 __name____main__으로 설정
  • 파일을 임포트하면 __name__모듈 이름으로 설정
# area.py
print(__name__)
-----------------
__main__
# run.py
import area
------------------
area

import를 이용하면 모듈과 관련된 코드를 실행해야 결과를 확인할 수 있다. 하지만 모듈을 작성할 때 매번 이런 방법을 이용하는 것은 상당히 번거로운 일이다. 그래서 모듈을 만들 때는 함수나 클래스가 잘 작성됐는지 확인하기 위해 모듈 내에서 함수나 클래스를 직접 호출한다.

if __name__ = "__main__" :
	직접 수행할 때만 실행되는 코드

같은 모듈에서 코드를 직접 수행할 때만 if __name__ = "__main__" : 안의 코드가 실행되고, import 하여 사용하면 수행되지 않는다.

모듈에서 코드를 직접 수행하는 경우와 임포트해서 사용하는 경우를 구분해서 코드를 실행하기 위한 구조는 아래와 같다.

if __name__ = "__main__" :
	직접 수행할 때만 실행되는 코드
else :
	임프트됐을 때만 실행되는 코드



main() 함수

  • main(작동시킬 부분)
# area.py
PI = 3.14

# 원의 면적을 구해 주는 함수
def circle(radius):
    return PI * radius * radius  

# 정사각형의 면적을 구해 주는 함수
def square(length):
    return length * length

# 함수들을 테스팅 하는 메인 함수
def main():
    # circle 함수 테스트
    print(circle(2) == 12.56)
    print(circle(5) == 78.4)

    # square 함수 테스트
    print(square(2) == 4)
    print(square(5) == 25)

if __name__ == '__main__':
    main()
# run.py
import area

# 면적 계산기 프로그램
def main():
    x = float(input('원의 지름을 입력해 주세요: '))
    print('지름이 {}인 원의 면적은 {}입니다.\n'.format(x, area.circle(x)))

    y = float(input('정사각형의 변의 길이를 입력해 주세요: '))
    print('변의 길이가 {}인 정사각형의 면적은 {}입니다.'.format(y, area.square(y)))

if __name__ == '__main__':
    main()
  • if __name__ == '__main__'
    main()
  • 파일에서 프로그램을 작동시키는 코드가 어디 있는지 쉽게 알 수 있기 때문에 코드의 가독성이 올라감 (코드의 흐름과 의도를 더 쉽게 이해)






내장 모듈

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

random 모듈

  • 임의의 숫자(난수) 발생
import random
random.random모듈함수()
random모듈함수설명사용 예
random()0 이상 1 미만 임의의 실수 반환random.random()
randint(a,b)a <= 정수 <= b 범위의 임의의 정수 반환random.randint(1,6)
uniform(a,b)a <= 실수 <= b 범위의 임의의 실수 반환random.uniform(0,1)
randrange(start, stop, step)range(start, stop, step)에서 임의의 정수를 반환random.randrange(0, 10, 2)
choice(seq)공백이 아닌 시퀀스(seq)에서 임의의 항목을 반환random.choice([1,2,3])
shuffle(seq)주어진 시퀀스의 요소를 임의의 순서로 섞음random.shuffle([1,2,3])
sample(population, k)시퀀스로 이뤄진 모집단(population)에서 중복되지 않는 k개의 인자 반환random.sample([1,2,3,4,5], 2)




datetime 모듈

  • 날짜 및 시간 관련 처리
import datetime
datetime.datetime모듈함수()
# datetime 모듈의 각 클래스에서 객체를 생성해 이용하는 방법
import datetime
date_obj = datetime.date(year, month, day)
time_obj = datetime.time(hour, minute, second)
datetime_obj = datetime.datetime(year, month, day, hour, minute, second)
# 객체를 생성하지 않고 각 클래스의 클래스 메소드를 이용하는 방법
import datetime
date_var = datetime.date.date_classmethod()
time_var = datetime.time.time_classmethod()
datetime_var = datetime.datetime.datetime_classmethod()

datetime의 메소드는 아래와 같다.

import datetime

# 1. 현재의 날짜와 시간 생성
now = datetime.datetime.now()
print(now)

# 2. 특정 날짜와 시간 생성
print(datetime.datetime(2023, 08, 20, 22, 26, 0))

# 3. 날짜와 시간 형식 지정 .strftime()
print(now.strftime("%Y-%m-%d %H:%M:%S"))

# 4. 날짜와 시간 연산 .timedelta()
print(now - datetime.timedelta(days=1))

# 5. 시간 바꾸기 .replace()
print(datetime.datetime.now().replace(hour = 9, minute=0, second = 0))

# 6. 다른 시간대로 변환하기 .timezone()
import pytz
new_timezone = pytz.timezone('Asia/Seoul')
new_datetime = now.astimezone(new_timezone)
print(new_datetime)
2023-08-20 22:35:15.986452
2023-08-20 22:26:00
2023-08-20 22:35:15
2023-08-19 22:35:15
2023-08-20 9:0:0
2023-08-20 22:35:15.986452+09:00

datetime 값에서 '연도'나 '월' 같은 값들을 추출하려면 각각 .year, .hour 등을 붙여주면 된다.

datetime.datetime.now().year
2023




calendar 모듈

  • 달력과 관련된 처리
calendar모듈함수설명사용예
calendar(year m=n)지정된 연도의 전체 달력을 문자열로 반환(기본 형식은 n=3개의 열)calendar.calendar(2023)
month(year, month)지정된 연도와 월의 달력을 문자열로 반환calendar.month(2023, 1)
monthrange(year, month)지정된 연도와 월의 시작 요일과 일수 반환,
요일의 경우 0(월요일) ~ 6(일요일) 사이의 숫자로 반환
calendar.monthrange(2023, 8)
firstweekday()달력에 표시되는 주의 첫 번째 요일값을 반환,
기본값으로는 월요일(0)로 지정됨
calendar.firstweekday()
setfirstweekday(weekday)달력에 표시되는 주의 첫 번째 요일을 지정calendar.setfirstweekday(5)
weekday(year,month,day)지정된 날짜의 요일 반환calendar.weekday(year,month,day)
isleap(year)지정된 연도가 윤년이면 True 반환calendar.isleap(2023)
  • 참고로, calendar.MONDAY = 0과 같다.



string 모듈

import string 

string.ascii_lowercase # 소문자 abcdefghijklmnopqrstuvwxyz
string.ascii_uppercase # 대문자 ABCDEFGHIJKLMNOPQRSTUVWXYZ
string.ascii_letters # 대소문자 모두 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
string.digits # 숫자 0123456789




Collections 모듈

from collections import Counter
my_str = input().strip()
max_count = max(Counter(my_str).values())
print(''.join(sorted([k for k,v in Counter(my_str).items() if v == max_count])))

import collections
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 7, 9, 1, 2, 3, 3, 5, 2, 6, 8, 9, 0, 1, 1, 4, 7, 0]
answer = collections.Counter(my_list)
# Counter({1: 4, 2: 3, 3: 3, 7: 3, 4: 2, 5: 2, 6: 2, 8: 2, 9: 2, 0: 2})




그 외 내장 모듈

  • math - 수학 관련 모듈
  • os - 운영체제 조작 및 정보 확인
  • os.path - 파일 경로 다룰 때
  • re - re.compile('정규표현식')
  • urllib.request - 인터넷의 내용을 가져오는 기능
  • pickle - 파이썬 객체를 byte형식으로 바꿔서 파일에 저장, 저장된 객체 불러오기
  • json - pickle과 유사하지만 객체를 JSON 형식으로 바꿈
  • copy - 객체 복사
  • sqlite3 - SQLite 데이터베이스 사용



🖐️ 더 자세히 알고 싶다면? 파이썬 표준 라이브러리에 관한 사이트 확인!






패키지 Package

  • 모듈 : 코드가 저장된 파일
  • 패키지 : 여러 모듈을 체계적으로 모아 놓은 것

여러 모듈을 폴더로 묶어서 계층적으로 관리한다.

패키지의 구조

  • 폴더 구조, 폴더 안에 파이썬 파일 존재 (__init__.py, module_name.py)
\--image
	__init__.py
    
    --effect   # 서브 패키지
    	rotate.py
        zoomIn.py
        __init__.py
    
    --filter   # 서브 패키지
    	blur.py
        sharpen.py
        __init__.py

각 폴더(패키지)에는 __init__.py 파일이 있는데, 이 파일은 해당 폴더가 패키지의 일부인 것을 알려주는 역할을 한다. 처음으로 패키지나 패키지 안에 있는 어떤 것을 import하면 가장 먼저 패키지의 __init__.py 파일에 있는 코드가 실행됩니다. (init = 초기화)

__init__.py 파일 활용 방법은 다양하다.

  • __init__.py 파일에서 임포트 사용하기 :
    • 패키지 import 시, 패키지 안에 있는 내용도 함께 import하고 싶다면 init 파일을 활용 : init 파일에 패키지와 함께 임포트하고 싶은 것들을 작성
    • init 파일에서 임포트하는 것은 패키지 안으로 임포트 : init 파일에서 임포트되는 것은 항상 package.으로 접근 가능
# __init__.py
from package import module
from package.module import function

# run.py
import package
package.module.function()
package.function()
  • __init__.py 파일에서 변수 정의하기 :
    • 패키지에 있는 여러 모듈이 필요로 하는 것들은 각 모듈에서 정의하지 않고 패키지 안에서 한 번만 정의하면 좋다. (패키지 레벨에서 정의하기)
    • init 파일에서 정의하고, 각 모듈에서 import하여 사용하기
    • init 파일에서 정의된 것들은 패키지 밖에서도 사용 가능
# __init__.py
var = x
def function(x)

# module.py
from package import var, function

# run.py
# 직접 import
from package import var
# 패키지 임포트 후 shapes. 으로 접근
import package    
package.var

__all__ 특수변수는 import * 했을 때 임포트 대상에서 어떤 것들을 가져와야 하는지를 정해 주는 변수이다. ('전체'가 무엇인지 정의)
모듈과 패키지에 모두 적용 가능하다.

from module import *    # 모듈의 모든 내용 임포트
from package import *   # 아무것도 임포트되지 않음

# 모듈의 경우, module.py 에서 __all__ 정의
__all__ = [function, function]

# 패키지의 경우, __init__.py 에서 __all__ 정의
__all__ = [module, module]




패키지의 생성

\--image
	__init__.py
    
    \--effect
        __init__.py
		rotate.py
        zoomIn.py

# 필요한 폴더 생성
mkdir C:\package_folder\image; C:\package_folder\image\effect

# 필요한 파일 생성
%%writefile C:\package_folder\image\__init__.py
%%writefile C:\package_folder\image|effect\__init__.py

# rotate 모듈에 pngread(), jpgread() 함수 생성
%%writefile C:\package_folder\image|effect\rotate.py
        
        def pngread() :
        print("pngread in rotate module")
        
        def jpgread() :
        print("jpgread in rotate module")

폴더와 파일이 잘 생성됐는지 확인하기 위해서는 윈도우 명령어 tree로 확인 가능하다. 참고로 이는 폴더의 구조를 표시하고, tree /F는 파일까지 표시한다.

!tree /F C:\package_folder




패키지 사용

  • import 패키지명.모듈명
import image.effect.rotate
import image.effect.rotate.pngread()   # 오류! 
# import 단독 사용 시 모듈 내의 함수 호출 불가능
  • from 패키지명 import 사용할 모듈명
from image.effect import rotate
rotate.pngread()
  • from 패키지명.모듈명 import 사용할 함수명
from image.effect.rotate import pngread
pngread()

모든 함수를 사용하려면 사용할 모듈명*을 입력하면 된다.
별명을 붙여서 모듈을 이용하려면 뒤에 as 별명을 추가하면 된다.




서브 패키지

폴더 안의 폴더 = 패키지 안의 패키지

# 패키지 안에 있는 패키지 임포트
from package import sub_pk

# 패키지 안에 있는 모듈 임포트
from package.sub_pk import area

# 모듈 안에 있는 함수 임포트
from package.sub_pk.area import circle

# import 뒤에는 . 을 쓸 수 없음 
from package import sub_pk.area # 오류






라이브러리

  • 패키지에 어떤 함수들이 있는지, 패키지의 함수들이 무엇을 하는지
  • 공식 문서를 통해 내용 확인
  • PyPI : 공식 패키지 저장소

스탠다드 라이브러리

  • 자료형, 내장 함수, 스탠다드 모듈
  • 파이썬 설치 시 기본적으로 포함되어 따로 설치할 필요 없음
  • 패키지가 아님

외부 라이브러리 (외부 패키지)

  • 파이썬을 사용하는 일반 개발자들이 패키지를 만들어서 PyPI에 업로드해 놓은 것
  • 직접 설치 필요

외부 라이브러리는 1) 패키지에 어떤 함수들이 있는지, 2) 패키지의 함수들이 무엇을 하는지 공식 문서를 통해 내용을 확인하여 활용할 수 있다.


🗃️ 대표적인 패키지 종류

데이터 분석 & 시각화

머신러닝

웹 개발

  • django : 웹 프레임워크 (웹 애플리케이션을 만들기 위한 뼈대) - 모든 기능 제공, 비교적 복잡 (공식 홈페이지)
  • flask : 웹 프레임워크 (웹 애플리케이션을 만들기 위한 뼈대) - 기본적인 기능, 비교적 간단 (공식 홈페이지)

기타

  • beautifulsoup4 : html or xml 문서를 파싱(원하는 데이터를 특정 패턴이나 순서로 추출해 가공해주는 것)해 주는 라이브러리로, 웹에서 원하는 데이터 긁어 오는 웹 스크래핑에 많이 사용 (공식 홈페이지)
  • selenium : 웹 브라우저 동작을 자동화해 주는 패키지 (클릭, 로그인, 검색, 스크롤링 등을 자동화), 웹 애플리케이션 테스팅 자동화 및 웹 스크래핑에 많이 사용 (공식 홈페이지), (가이드)
  • requests : 간편한 http 라이브러리 (쉽게 http 요청 보내기) (공식 홈페이지)
  • opencv : 컴퓨터 비전에 많이 사용되는 라이브러리 (이미지 프로세싱, 얼굴 인식, 문자 인식 등 많은 기능 제공) (공식 홈페이지)
    설치 : opencv.python, import : import cv2




⚙️ 설치 방법

  • PyPI (The Python Package Index) : 공식 패키지 저장소 (링크)
  • PIP (Package Installer for Python) : 패키지 매니저

1. PIP 설치

  • Python 3.4 이후부터는 자동 설치
  • 설치 확인 : cmd(windows) or 터미널(MacOS)에서 pip3 입력 시 오류 없으면 설치되어있는 것

2. PyCharm으로 외부 패키지 설치

  1. (Windows) File > Settings > Project pythonProject > 우측 상단 +
  2. (MacOS) Menu : Pycharm > Preferences > Project > Project Interpreter > 하단 +
  3. 설치하고자 하는 외부 패키지 검색 후 install package
  4. 관련 패키지까지 모두 설치 완료

파이참은 프로젝트 별로 외부 패키지를 따로 관리한다.
그래서 설치한 패키지는 해당 프로젝트에서만 사용 가능하다.

3. 커맨드 라인으로 외부 패키지 설치

  • windows : cmd, MacOS : 터미널
  1. cmd or 터미널 > pip3 install package_name 입력 : 설치
  2. cmd or 터미널 > pip3 uninstall package_name 입력 : 삭제
# pandas 설치하기
pip3 install pandas
pip3 install pandas==1.1.1   # 특정 버전 설치




👉 실습

(1) 유튜브 영상 다운로드 받기

yt-dlp 설치 yt-dlp 패키지 소스 코드
➁ 파이썬에 내용 입력

import yt-dlp
# yt-dlp 패키지 > Youtudb 모듈 > YoutubeDL() 클래스
# .download() 함수로 영상 다운로드 받기

with yt_dlp.YoutubeDL() as ydl :
	ydl.download(['동영상 url'])  # 영상 주소 혹은 재생목록 주소

➂ (선택) 다운로드 옵션 설정 (옵션 설명)

# 옵션을 주려면 YoutubeDL()의 파라미터로 ydl_ops 추가

import yt-dlp

ydl_opt = {

}

with yt_dlp.YoutubeDL(ydl_ops) as ydl :
	ydl.download(['youtube url'])  # 영상 주소 혹은 재생목록 주소

자세한 내용은 공식 문서 확인!



(2) 데이터 분석하기

pandas 설치 pandas 패키지 소스 코드

  • 데이터를 읽어와서 테이블 형식(데이터프레임)으로 제작하기
  • 데이터프레임을 쉽게 다룰 수 있는 기능을 제공하기

코로나 바이러스 데이터 다운로드
➂ 파이썬에 내용 입력

import pandas as pd
import matplotlib.pyplot as plt


# 디스플레이 옵션 설정
pd.set_option('display.width', 320)
pd.set_option('display.max_columns', 20)


# csv 파일 읽어와서 dataframe으로 저장
df_covid = pd.read_csv('데이터 파일 경로를 넣어주세요')
print(df_covid)


# 나라, 확진자, 사망자 데이터만 추출
df_countries_cases = df_covid[['Country', 'Confirmed', 'Deaths']]
df_countries_cases.index = df_countries_cases["Country"]
df_countries_cases = df_countries_cases.drop(['Country'], axis=1)
print(df_countries_cases)


# 나라별 사망률 구하기
df_countries_cases['Death Rate (Per 100)'] = 100 * df_countries_cases['Deaths'] / df_countries_cases['Confirmed']
print(df_countries_cases)


# 사망률 가장 높은 10개 나라 (사망자 1000명 이상)
df_top10_countries_dr = df_countries_cases[df_countries_cases['Deaths'] >= 1000].sort_values('Death Rate (Per 100)')[-10:]
print(df_top10_countries_dr)


# 사망률 바 그래프
plt.barh(df_top10_countries_dr.index, df_top10_countries_dr['Death Rate (Per 100)'], color="darkcyan")
plt.tick_params(size=5, labelsize=11)
plt.xlabel("Death Rate (Per 100)", fontsize=14)
plt.title("Top 10 Countries by Death Rate", fontsize=18)
plt.grid(alpha=0.3)
plt.show()



(3) 웹 크롤링 자동화하기

selenium 설치
크롬 웹드라이버 다운로드
➂ 파이썬에 내용 입력

import time

from selenium import webdriver
import requests


# 웹드라이버 생성
driver = webdriver.Chrome('/Users/jho/Desktop/chromedriver')
driver.implicitly_wait(3)


# https://workey.codeit.kr/costagram 접속
time.sleep(1)
driver.get('https://workey.codeit.kr/costagram')


# 로그인 버튼 클릭
time.sleep(1.5)
driver.find_element_by_class_name('top-nav__login-link').click()
# ID 입력
time.sleep(1.5)
driver.find_element_by_class_name('login-container__login-input').send_keys('codeit')
# 비밀번호 입력
time.sleep(1.5)
driver.find_element_by_class_name('login-container__password-input').send_keys('datascience')
# 로그인
time.sleep(1.5)
driver.find_element_by_class_name('login-container__login-button').click()


# 웹 페이지 가장 밑으로 스크롤
# scrollHeight 가져오기
last_height = driver.execute_script("return document.body.scrollHeight")

while True:
    # scrollHeight 까지 스크롤
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(1)

    # scrollHeight 비교
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break
    last_height = new_height


# 이미지 다운로드
for elt in driver.find_elements_by_class_name('post-list__post.post'):
    # 'style'이라는 속성에서 이미지 url (이미지 주소) 추출
    style_string = elt.get_attribute('style')
    img_url = 'https://workey.codeit.kr' + style_string.split(' url("')[1].split('")')[0]
    # 이미지 저장할 경로 정의
    img_path = '/Users/jho/Desktop/my_images/' + img_url.split('/')[-1]
    # requests 패키지 써서 이미지 다운로드
    response = requests.get(img_url)
    if response.status_code == 200:
        with open(img_path, 'wb+') as f:
            f.write(response.content)



API (Application Programming Interface)
패키지의 기능을 사용자에게 노출하는 함수들 또는 클래스들
(그래서 pandas > io 서브패키지 안에 io에서 사용자들이 쓸만한 함수들, 즉 read 함수들을 모아 놓은 api.py 파일이 존재하는 것이다. 그리고 pandas 패키지의 init 파일에서는 pandas/io/api.py 파일에 있는 함수들을 모두 임포트 해주었다.)
이처럼 패키지의 init 파일에서는 패키지의 핵심 API를 쉽게 사용할 수 있도록 임포트해 주는 게 좋다.

profile
planning design development with data

0개의 댓글