본문 바로가기
DEV/파이썬 이론

파이썬 코딩 :: 파이썬 모듈(Module)

by 올커 2022. 9. 5.

파이썬 모듈(Module)


1. 모듈(Module)

 - 스크립트 작성 시 자주 사용되는 클래스와 함수로 인해 코드가 길어짐, 중복발생을 방지하기 위해

   변수, 함수, 클래스 등을 모아 놓은 스크립트 파일

 

2. 모듈의 장점

 - 한 파일에서 구현하고자 하는 기능이 더 명확해지므로 코드 관리가 쉬워진다.

 - 코드 재사용이 용이하다. (특정 기능이 여러 프로그램에 필요한 경우 만들어진 모듈을 가져와서 사용)

 

3. 모듈 만들기

 - 원, 정사각형의 면적을 구하는 모듈 만들기

# area.py
PI = 3.14

def circle(r):
	return PI * r * r


def square(l):
	return l * l

4. 모듈 불러오기

 (1) 모듈 불러와서 사용하기 -1

 - 모듈을 'import 모듈명' 으로 가져온다.

      (*아래 예시에서 area.py와 run.py는 같은 경로상에 위치하고 있다고 가정)

# run.py
import area

print(area.circle(2))
print(area.square(3))
print(area.PI)

>>> 12.56
>>> 9
>>> 3.14

  area모듈에서 선언한 함수(circle, square)를 '모듈명.함수명()' 으로 불러와 사용이 가능하며,

  area모듈에서 정의된 변수(PI) 역시 '모듈명.변수명' 으로 불러올 수 있다.

 

  자주쓰는 모듈명을 간소화 하고 싶을 경우, 아래처럼 별칭(Alias)을 사용하여 간소화가능하다.

# run.py
import area as ar

print(ar.circle(2))
print(ar.square(3))
print(ar.PI)

>>> 12.56
>>> 9
>>> 3.14

 

 (2) 모듈 불러와서 사용하기 -2

 - 모듈과 함수를 'from 모듈명 import 함수명1, 함수명2, ...' 으로 가져온다.

      (*아래 예시에서 area.py와 run.py는 같은 경로상에 위치하고 있다고 가정)

# run.py
from area import circle, square, PI

print(circle(2))
print(square(3))
print(PI)

>>> 12.56
>>> 9
>>> 3.14

  area모듈에서 선언한 함수(circle, square)를 '함수명()' 으로 불러와 사용이 가능하며,

  area모듈에서 정의된 변수(PI) 역시 '변수명' 으로 불러올 수 있다.

 

  자주쓰는 함수명을 간소화 하고 싶을 경우, 아래처럼 별칭(Alias)을 사용하여 간소화가능하다.

# run.py
from area import circle as cir, square as sq, PI

print(cir(2))
print(sqe(3))
print(PI)

>>> 12.56
>>> 9
>>> 3.14

 (3) 모듈 불러와서 사용하기 -3

 - 모듈에 저장된 모든 함수, 변수들을 사용하고자 할 때에는 import 뒤에 * 만 붙여줘도 된다.

   (하지만 이 경우 파일에서 사용된 함수가 어떤 모듈에 속해있는지 출처가 불분명해지는 단점이 있다.)

# run.py
from area import *

print(circle(2))
print(square(3))
print(PI)

>>> 12.56
>>> 9
>>> 3.14

 (4) 스탠다드 라이브러리

 - int, float, string과 같은 자료형

 - print, dir같은 내장함수

 - 유용한 기능을 제공하는 모듈(스탠다드 모듈) : math, random, os, datetime, os.path, re, pickle, json, copy, sqlite3 등

   *참고 : 파이썬 기초이론 :: 모듈(Module) 기본, 스탠다드 라이브러리

  ① os.path : 파일 경로를 다룰 때 사용

import os.path

# 프로젝트 디렉토리 경로 '/Users/codeit/PycharmProjects/standard_modules'
# 현재 파일 경로 '/Users/codeit/PycharmProjects/standard_modules/main.py'

# 주어진 경로를 절대 경로로
print(os.path.abspath('..'))

# 주어진 경로를 현재 디렉토리를 기준으로 한 상대 경로로
print(os.path.relpath('/Users/codeit/PycharmProjects'))

# 주어진 경로들을 병합
print(os.path.join('/Users/codeit/PycharmProjects', 'standard_modules'))



>>> /Users/codeit/PycharmProjects
>>> ..
>>> /Users/codeit/PycharmProjects/standard_modules

  ② re : Regular Expression(정규표현식) 특정한 규칙/패턴을 가진 문자열을 표현할 때 사용

import re 

# 알파벳으로 구성된 단어들만 매칭
pattern = re.compile('^[A-Za-z]+$')
print(pattern.match('I'))
print(pattern.match('love'))
print(pattern.match('python3'))

print()

# 숫자가 포함된 단어들만 매칭
pattern = re.compile('.*\d+')
print(pattern.match('I'))
print(pattern.match('love'))
print(pattern.match('python3'))


>>> <re.Match object; span=(0, 1), match='I'>
>>> <re.Match object; span=(0, 4), match='love'>
>>> None

  ③ pickle : 파이썬 오브젝트(객체)를 바이트(byte)형식으로 바꾸어 파일에 저장하거나, 저장된 오브젝트를 읽어옴

import pickle

# 딕셔너리 오브젝트
obj = {'my': 'dictionary'}  

# obj를 filename.pickle 파일에 저장
with open('filename.pickle', 'wb') as f:
    pickle.dump(obj, f)

# filename.pickle에 있는 오브젝트를 읽어옴 
with open('filename.pickle', 'rb') as f:
    obj = pickle.load(f)

print(obj)


>>> {'my': 'dictionary'}

  ④ json : pickle과 유사하지만 오브젝트를 JSON형식으로 바꿔줌.

import json

# 딕셔너리 오브젝트
obj = {'my': 'dictionary'}  

# obj를 filename.json 파일에 저장
with open('filename.json', 'w') as f:
    json.dump(obj, f)

# filename.json에 있는 오브젝트를 읽어옴 
with open('filename.json', 'r') as f:
    obj = json.load(f)

print(obj)


>>> {'my': 'dictionary'}

  ⑤ copy : 파이썬 오브젝트를 복사할 때 사용

import copy

# '=' 연산자는 실제로 리스트를 복사하지 않음
# 리스트를 복사하려면 슬라이싱을 사용하거나 copy.copy() 함수를 사용해야 함
a = [1, 2, 3] 
b = a
c = a[:]
d = copy.copy(a)
a[0] = 4
print(a, b, c, d)

# 하지만 오브젝트 안에 오브젝트가 있는 경우 copy.copy() 함수는 가장 바깥에 있는 오브젝트만 복사함 
# 오브젝트를 재귀적으로 복사하려면 copy.deepcopy() 함수를 사용해야 함
a = [[1,2,3], [4,5,6], [7,8,9]]
b = copy.copy(a)
c = copy.deepcopy(a)
a[0][0] = 4
print(a, b, c)

>>> [4, 2, 3] [4, 2, 3] [1, 2, 3] [1, 2, 3]
>>> [[4, 2, 3], [4, 5, 6], [7, 8, 9]] [[4, 2, 3], [4, 5, 6], [7, 8, 9]] [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

  ⑥ sqlite3 : 파이썬에서 SQLite 데이터베이스를 사용할 때

import sqlite3

# 데이터베이스 연결
conn = sqlite3.connect('example.db')

# SQL 문 실행 
c = conn.cursor()
c.execute('''SELECT ... FROM ... WHERE ... ''')

# 가져온 데이터를 파이썬에서 사용
rows = c.fetchall()
for row in rows:
    print(row)

# 연결 종료
conn.close()

 (5) 모듈이 저장된 경로 확인/추가하기

import sys

print(sys.path)


>>> ['d:\\test\\python_basic', 'C:\\Python310\\python310.zip',
     'C:\\Python310\\DLLs', 'C:\\Python310\\lib', 'C:\\Python310',
     'd:\\test\\python_basic\\venv',
     'd:\\test\\python_basic\\venv\\lib\\site-packages']

 - sys라는 모듈을 불러와서 'sys.path'를 확인해보면 위와 같은 결과를 확인할 수 있다.

   모듈을 찾기 위해서 위의 경로를 순차적으로 확인하고, 모듈을 못찾을시 오류가 발생한다.

   모듈을 찾는 순서는 가장 먼저 파일이 저장된 폴더, 그리고 파이썬이 디폴트로 정해주는 경로들을 순서로 확인한다.

   가장 마지막 경로 site-packages는 외부 패키지가 저장되는 폴더이다.

 - 모듈 검색 경로에 새로운 경로 추가하기

 ① 경로 직접 추가하기(append)

   sys.path는 리스트 자료형이기 때문에 아래와 같이 경로를 추가할 수 있다.

  예를들어 바탕화면의 경로를 추가한다면 아래와 같이 추가가 가능하다.

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

 ② 영구적으로 경로 추가하기(PyCharm)

    아래의 단계로 경로를 추가하면 매번 append하지 않아도 된다.

    설정 → Project → Project Interpreter → 톱니바퀴 버튼 → Show all → 파일 경로 아이콘 클릭

    → +버튼 누르고 원하는 경로 추가

 (6) 스크립트와 모듈 구분

 - 모듈 : 프로그램에 필요한 변수들이나 함수들을 정의해 놓은 파일`

# area.py

PI = 3.14

def circle(radius):
    return PI * radius * radius

def square(length):
    return length * length

 - 스크립트 : 프로그램을 작동시키는 코드를 담은 실행 용도의 파일

# run.py

import area

x = float(input('원의 반지름 입력 : '))
print("반지름 : {}, 원의 면적 : {}".format(x, area.circle(x)))

y = float(input('정사각형의 변의 길이 입력 : '))
print("변의 길이 : {}, 정사각형 면적 : {}".format(y, area.square(y)))

 (7) name 특수 변수(__name__ )

 - 모듈을 스크립트에서 import할 시, 만약 모듈에 실행 함수가 있다면 import하면서 실행되는 문제점이 있다.

   이를 보여주고 싶지 않을 때에는 __name__을 활용한다.

 -  __name__은 모듈의 이름을 저장해놓은 변수이다.

 - 직접 실행할 경우 __name__의 값은   →    __main__이 되고,

    import해서 사용할 경우 __name__의 값은  →   원래 모듈 이름으로 설정된다.

# area.py
print('area 모듈 이름 : {}'.format(__name__))

PI = 3.14

def circle(radius):
    return PI * radius * radius


def square(length):
    return length * length
    
print("Hello")
    
>>> area 모듈 이름 : __main__
>>> Hello
# run.py

print('run 파일 이름 : {}'.format(__name__))

import area

x = float(input('원의 반지름 입력 : '))
print("반지름 : {}, 원의 면적 : {}".format(x, area.circle(x)))

y = float(input('정사각형의 변의 길이 입력 : '))
print("변의 길이 : {}, 정사각형 면적 : {}".format(y, area.square(y)))


>>> run 파일 이름 : __main__
>>> area 모듈 이름 : area
>>> Hello
>>> 원의 반지름 입력 :
>>> ...

 - area.py 모듈에 있는 함수 "Hello"를 출력하고 싶지 않을 경우 아래와 같이 변경하면,

   run.py에서 모듈을 import 해와도 모듈에 있는 함수가 출력되지 않는다.

# area.py
print('area 모듈 이름 : {}'.format(__name__))

PI = 3.14

def circle(radius):
    return PI * radius * radius


def square(length):
    return length * length
    
if __name__ == '__main__':
	print("Hello")
    
>>> area 모듈 이름 : __main__
>>> Hello
# run.py

print('run 파일 이름 : {}'.format(__name__))

import area

x = float(input('원의 반지름 입력 : '))
print("반지름 : {}, 원의 면적 : {}".format(x, area.circle(x)))

y = float(input('정사각형의 변의 길이 입력 : '))
print("변의 길이 : {}, 정사각형 면적 : {}".format(y, area.square(y)))


>>> run 파일 이름 : __main__
>>> area 모듈 이름 : area
>>> 원의 반지름 입력 :
>>> ...

 - 아래 수식은 __name__이 직접 실행, 임포트 했을 때 값이 다른 속성을 활용한 방법이다.

if __name__ == '__main__':
	print("Hello")

 - 위 코드는 아래와 같이 main() 함수를 만들어 호출하는 방식으로 활용할 수 있다.

   프로그램을 작동시키는 부분을 main() 함수안에 넣어주고, 

   if문 안에서 main() 함수를 호출하는 방식이다.

# run.py
import area

# 면적 계산 프로그램
def main():
    x = float(input('원의 반지름 입력 : '))
    print("반지름 : {}, 원의 면적 : {}".format(x, area.circle(x)))

    y = float(input('정사각형의 변의 길이 입력 : '))
    print("변의 길이 : {}, 정사각형 면적 : {}".format(y, area.square(y)))

if __name__ == '__main__':
    main()

 - 이렇게 main함수를 사용하면 파일에서 프로그램을 작동시키는 코드가 어디있느지 쉽게 알 수 있기 때문에

   코드의 가독성이 높아지고, 코드의 흐름과 의도를 더 쉽게 이해할 수 있게 되는 장점이 있다.

 

반응형

댓글