모듈화를 이해하기에 앞서 패키징을 이해하고 오면 모듈화에 대한 이해도를 더 높일 수 있습니다.
패키징이란?
일단 따라치고 이해하면 편하다
setuptools
, dotenv
, mysql-connector-python
python3 -m pip install setuptools python-dotenv mysql-connector-python
파이썬에서 모듈은 함수나 변수, 클래스들을 담은 파일을 의미한다. 모듈을 활용하면 코드를 더욱 모듈화하고, 코드 재사용성을 높일 수 있어 유지보수성과 가독성을 향상시킬 수 있다.
아래의 Directory 구조는 아래 보여줄 코드를 기반으로 함
../python_workspace/example_fibo/
├── setup.py
└── fibonacci_package/
├── __init__.py
└── data_handler.py
└── fibonacci_runner.py
└── mysql_config.py
└── mysql_data_repository.py
~/env_example/.env
패키지를 빌드하고 설치하는데 사용
from setuptools import setup, find_packages
setup(
name='fibonacci',
version='1.0',
description='이 것은 피보나치 예제입니다',
author='seongkeun',
author_email='osk3856@gmai.com',
packages=find_packages(),
install_requires=[
'mysql-connector-python',
'python-dotenv'
]
)
__init__.py
패키지의 초기화 파일
from .fibonacci_runner import run_fibonacci
__all__ = ['run_fibonacci']
메인과 repository 의 연결지점. 데이터를 핸들링하는 파일
from .mysql_data_repository import MysqlDataRepository
class DataHandler:
def __init__(self, start_date, end_date, user, password, host, port, database):
self.start_date = start_date
self.end_date = end_date
self.mysql_repo = MysqlDataRepository(
start_date = start_date,
end_date = end_date,
user = user,
password = password,
host = host,
port = port,
database = database
)
def put_data(self, date, data):
return self.mysql_repo.put_data(date, data)
def extract_data(self) :
return self.mysql_repo.get_data()
def fibonacci_tail(self, n, a=0, b=1):
if n == 0:
return a
elif n == 1:
return b
else:
return self.fibonacci_tail(n-1, b, int(a)+int(b))
def calc_fibo(self, data_list) :
result = []
for date, num in data_list:
result.append(self.fibonacci_tail(num))
return result
메인이 될 파일이다
from .mysql_config import MysqlConfig
from .data_handler import DataHandler
def run_fibonacci(start_date=None, end_date=None, date=None, data=None):
mysql_config=MysqlConfig.get_mysql_config(start_date, end_date)
dh = DataHandler(
start_date = mysql_config.start_date,
end_date = mysql_config.end_date,
user = mysql_config.user,
password = mysql_config.password,
host = mysql_config.host,
port = mysql_config.port,
database = mysql_config.database
)
for d, dt in zip(date, data):
dh.put_data(d, dt)
data_list = dh.extract_data()
fibonacci_list = dh.calc_fibo(data_list)
return fibonacci_list
이 파일은 MySQL Connection 에 필요한 파일입니다
사실상 이 글에 필요없는 코드이지만 나중을 위해 이해정도만 해주세요.
from dotenv import load_dotenv
import os
import re
class MysqlConfig:
def __init__(self, start_date, end_date, user, password, host, port, database):
self.start_date = start_date
self.end_date = end_date
self.user = user
self.password = password
self.host = host
self.port = port
self.database = database
@classmethod
def get_mysql_config(cls, start_date, end_date):
load_dotenv(dotenv_path="/env_example/.env")
database_url=os.getenv("DATABASE_INFO")
database_array = re.split('\W+', database_url)
user = database_array[1]
password = database_array[2]
host = database_array[3]
port = database_array[4]
database = database_array[5]
return cls(
start_date=start_date,
end_date=end_date,
user=user,
password=password,
host=host,
port=port,
database=database
)
위 코드를 만들기 전에
~/env_example/
디렉토리에.env
파일을 만들고 아래 url 형식으로 본인의 database 정보로 변경해서 넣어주세요
DATABASE_INFO=mysql://root:password@localhost:3306/flower
mysql
: 어떤 DATABASE 를 사용하는지root
: userpassword
: passwordlocalhost
: host3306
: portflower
: database 이름원래는 MySQL 로 다루려고 했으나 sqlite3 라는 파이썬 임시데이터베이스로 처리 밑에 데이터베이스 Connect 하는 코드도 첨부함
import sqlite3
class MysqlDataRepository:
def __init__(self, start_date, end_date, user, password, host, port, database):
self.start_date = start_date
self.end_date = end_date
# SQLite 데이터베이스 연결
self.conn = sqlite3.connect('fibonacci_example.db')
self.cursor = self.conn.cursor()
# fibonacci 테이블이 존재하지 않는 경우에만 생성
self.cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='fibonacci';")
result = self.cursor.fetchone()
if not result:
self.cursor.execute('''CREATE TABLE fibonacci
(date date, data INT)''')
self.conn.commit()
def close_mysql_connection(self) :
self.cursor.close()
self.conn.close()
def put_data(self, date, data) :
# 데이터 삽입
self.cursor.execute(f"INSERT INTO fibonacci VALUES ('{date}', '{data}')")
self.conn.commit()
return True
def get_data(self) :
self.cursor.execute(f"SELECT *\
FROM fibonacci\
WHERE date BETWEEN '{self.start_date}' AND '{self.end_date}'")
result = self.cursor.fetchall()
self.close_mysql_connection()
return result
아래 코드는 이 글에서 사용되지 않는 코드입니다. MySQL에 어떻게 Connection 하는 것인지 보여만 드리기 위해 첨부했습니다
import mysql.connector
class MysqlDataRepositoryOriginal:
def __init__(self, start_date, end_date, user, password, host, port, database):
self.start_date = start_date
self.end_date = end_date
self.conn = mysql.connector.connect(
user=user,
password=password,
host=host,
port=port,
database=database
)
self.cursor = self.conn.cursor()
def close_mysql_connection(self) :
self.cursor.close()
self.conn.close()
def get_data(self) :
self.cursor.execute(f"SELECT *\
FROM table\
WHERE date BETWEEN '{self.start_date}' AND '{self.end_date}'")
result = self.cursor.fetchall()
self.close_mysql_connection()
return result
setup.py 가 있는 directory 를 터미널로 들아가서
python setup.py sdist
와 같이 친다
아래와 같이 마지막에 removing... 이 나오면 성공
파일이 위와 같이 만들어졌을겁니다
자물쇠 마크있는 것은 신경쓰지 않아도 됩니다.
저처럼 도커로 바운드 마운트 하고있는게 아니라면 저렇게 자물쇠 마크가 자동으로 생기지는 않을테니까요
Directory
./dist
에서 생성된 tar파일
(setup.py 를 저와 똑같이 따라쳤다면fibonacci-1.0.tar.gz
생성됨) 을
fibonacci-1.0.tar.gz
를 설치하면 기본 패키지 저장소인/usr/local/lib/python3.11/site-packages
directory 에 저장이 됩니다.
(/lib
후에 있는 디렉토리명은 파이썬 버전마다 다르기에lib
디렉토리 부터는 들어가서 확인하는 것을 추천)
2-1. (똑같이 따라하지 않으신 분들은 ls dist/
로 dist 내부에 있는 .tar.gz
파일명 확인하세요)
pip install ./dist/fibonacci-1.0.tar.gz
위와 같이 나왔다면 모듈을 파이썬에서 사용할 수 있습니다.
하지만 만약 내가 원하는 저장소가 따로 있으면 아래와 같이 패키지 인스톨 하셔도 됩니다
(원하는 경로가 /dist-packages
라고 가정)
pip install ./dist/fibonacci-1.0.tar.gz --target=/usr/local/lib/python3.11/dist-packages
하지만 Python 이 패키지를 찾을 수 있게 패키지 경로가 추가 되어있어야 합니다. 패키지 경로 추가는 아래처럼 하시면 됩니다.
(local.pth
는 Python 패키지 경로 파일로 site-packages
의 하위 디렉토리로 추가시켜주는 파일입니다)
echo "/usr/local/lib/python3.11/dist-packages" | sudo tee -a /usr/local/lib/python3.11/site-packages/local.pth
2-2. pip list | grep "fibo"
를 입력하면 내 모듈이 저장된 것을 확인할 수 있습니다. 또한 pip show fibonacci
를 입력하면 설치경로 및 패키지에대한 정보를 얻을 수 있습니다.
2-3. /usr/local/lib/python3.11/site-packages
경로에서 ll | grep "fibo"
OR ls | grep "fibo"
를 입력해보면 다음과 같은 패키지가 만들어져있는 것을 확인할 수 있습니다. .dist-info
는 말그대로 패키지에 대한 설명이고 우리가 필요한건 fibonacci_package
입니다. 파이썬에서 이 패키지 명으로 import
가 가능합니다
2-4. 이제 setup.py
파일이 존재하는 경로에 있는 /fibonacci.egg-info
, /dist
, fibonacci-1.0.tar.gz
는 삭제해도 됩니다.
단, 만약을 위해 setup.py
와 /fibonacci_package
는 지우지 마세요
자, 이제 거의 다 왔습니다. 본인이 사용하는 python 을 작업하는 디렉토리에서 이제 이 모듈을 불러와서 사용해볼 것입니다. 저는 그냥
setup.py
가 있던 디렉토리에main.py
을 만들었습니다
from fibonacci_package import run_fibonacci
import json
import sys
date = ["2023-02-18", "2023-02-26", "2023-02-20", "2023-02-28", "2023-03-01", "2023-03-02"]
data = [7,11,5,9,15,3]
start_date="2023-02-22"
end_date="2023-03-01"
result = run_fibonacci(start_date=start_date, end_date=end_date, date=date, data=data)
# print(result) 도 가능하지만 sys.std 객체는 출력을 직접 제어할 수 있는 장점이 있습니다
json_data = json.dumps(result)
sys.stdout.write(json_data)
저는 jupyter lab 을 이용하기에 main.py 가 있는 디렉토리에서 터미널을 열어서 python3 -m main
을 입력해서 다음과 같이 결과를 확인했습니다. 커널이 연동되어있는 IDE 쓰시는 분들은 그냥 실행시켜서 확인해보면 될 것 같습니다.
이 패키지를 삭제하고싶으면 아무 디렉토리에서 pip uninstall fibonacci
를 입력하시면 됩니다
위 예시의 최종 디렉토리 구조는 다음과 같다
../python_workspace/example_fibo/
├── main.py
├── setup.py
└── fibonacci_package/
├── __init__.py
└── data_handler.py
└── fibonacci_runner.py
└── mysql_config.py
└── mysql_data_repository.py
~/env_example/.env
~/usr/local/lib/python3.11/site-packages/
├── fibonacci-1.0.dist-info/
├── fibonacci_package/