고객 정보 관리 시스템 만들기 실습5 에서 class화를 진행하였다.
[Python][파이썬] 고객 정보 관리 시스템 만들기 실습 5 (tistory.com)
[Python][파이썬] 고객 정보 관리 시스템 만들기 실습 5
파이썬에도 class가 있다는 것을 알게 되었고 class를 사용하면 어떤 점들이 좋은지 알아보고 실습 예제를 class를 사용하여 바꾸어 보자. 클래스를 사용하는 이유 코드의 구조화 및 조직화: 클래스
codingwithyou.tistory.com
이젠 do_S와 do_L 말고 다른 함수들도 가져오고,
class의 default함수(초기값) 만들고 main에 있던 변수 self변수로 가져와 보자.
추가로 자바에서 배운 model과 view를 적용해 class를 분할 해 보자.
1. do_I, do_P, do_C, do_N, do_U, do_D 모듈 class 내부로 가져오기
2. class의 클래스의 생성자 (default함수) 만들기
3. CustomerController클래스, CustomerView클래스, CustomerModel클래스 나눠주기 (파일 분리)
1. do_I, do_P, do_C, do_N, do_U, do_D 모듈 class 내부로 가져오기
- self변수 붙여주기
- import 지워주기
import pickle
import sys
import os
import re
class Customer:
def print_menu(self):
return input('''
다음 중에서 하실 작업의 메뉴를 입력하세요.
I - 고객 정보 입력
P - 이전 고객 정보 조회
C - 현재 고객 정보 조회
N - 다음 고객 정보 조회
U - 현재 고객 정보 수정
D - 현재 고객 정보 삭제
S - 고객 정보 저장
Q - 프로그램 종료
''').upper()
def chk_input_data(self, msg, func, upper=True):
while True:
x = input(msg)
if upper:
x = x.upper()
if func(x):
break
else:
print('잘못 입력하셨습니다. 다시 입력 해 주세요.')
return x
def check_email_addr(self, email_addr):
pattern = re.compile('^[a-zA-Z][a-zA-Z0-9]{3,10}@[a-zA-Z0-9]{2,8}[.][a-zA-Z]{2,5}$')
return pattern.search(email_addr)
def do_I(self, customers, index):
print('고객정보 입력')
customer = { 'name':'', 'gender': '', 'email': '', 'year': 0 }
customer['name'] = self.chk_input_data('이름을 입력하세요 : ', lambda x: True if len(x) > 2 else False, upper=True)
customer['gender'] = self.chk_input_data('성별 (M/F)를 입력하세요 : ', lambda x: True if x in ('M', 'F') else False)
customer['email'] = self.chk_input_data('이메일 주소를 입력하세요 : ', lambda x: True if self.check_email_addr(x) else False, upper=False)
customer['year'] = self.chk_input_data('출생년도 4자리 입력하세요 : ', lambda x: True if len(x) == 4 and x.isdigit() else False)
customers.append(customer)
index = len(customers) - 1
return index
def do_P(self, customers, index):
print('이전 고객 정보 조회')
if index <= 0:
print('이전 데이터로 이동 불가.')
print(index)
else:
index -= 1
print(f'{index}번째 고객 정보 입니다.')
print(customers[index])
return index
def do_C(self, customers, index):
print('현재 고객 정보 조회')
print('>>>>>', index)
if index >= -1:
print(f'{index}번째 고객 정보 입니다.')
print(customers[index])
else:
print('입력된 정보가 없습니다. 정보 입력은 I를 선택하세요.')
def do_N(self, customers, index):
print('다음 고객 정보 조회')
if index >= (len(customers) - 1):
print('이후 데이터 이동 불가')
print(index)
else:
index += 1
print(f'{index}번째 고객 정보 입니다.')
print(customers[index])
return index
def do_U(self, customers, index):
print('현재 고객 정보 수정')
customer = { 'name':'', 'gender': '', 'email': '', 'year': 0 }
customer['name'] = self.chk_input_data('수정할 이름을 입력하세요 : ', lambda x: True if len(x) > 2 else False)
customer['gender'] = self.chk_input_data('수정할 성별 (M/F)를 입력하세요 : ', lambda x: True if x in ('M', 'F') else False)
customer['email'] = self.chk_input_data('이메일 주소를 입력하세요 : ', lambda x: True if self.check_email_addr(x) else False, upper=False)
customer['year'] = self.chk_input_data('수정할 출생년도 4자리 입력하세요 : ', lambda x: True if len(x) == 4 and x.isdigit() else False)
print(customer)
customers[index] = customer
def do_D(self, customers, index):
if not customers:
print("고객 정보가 없습니다.")
else:
print(f'현재 고객 정보 {customers[index]["name"]} 삭제')
print('index : ',index)
del customers[index]
if index >= len(customers):
index = len(customers) - 1
return index
def do_S(self, customers):
try:
with open('cust/customers.pickle', 'wb') as fp:
pickle.dump(customers, fp)
except Exception as e:
print('저장하는데에 실패하였습니다.', e)
def do_L(self):
file_path = 'cust/customers.pickle'
if os.path.exists(file_path):
with open(file_path, 'rb') as fp:
return pickle.load(fp)
else:
return list()
#main
def main(self):
customers = self.do_L()
index = -1
while True:
menu = self.print_menu()
if menu == 'I':
self.index = self.do_I(self.customers, self.index)
print('index :', self.index)
print('customers : ', self.customers)
elif menu == 'P':
self.index = self.do_P(self.customers, self.index)
elif menu == 'C':
self.do_C(self.customers, self.index)
elif menu == 'N':
self.index = self.do_N(self.customers, self.index)
elif menu == 'U':
self.do_U(self.customers, self.index)
elif menu == 'D':
self.index = self.do_D(self.customers, self.index)
elif menu == 'S':
self.do_S(self.customers)
elif menu == 'Q':
self.do_S(self.customers)
print('저장이 완료되었습니다.')
print('안녕히가세요~')
sys.exit()
else:
print('잘못 입력하셨습니다. 다시 입력 해주세요')
if __name__ == '__main__':
a = Customer()
a.main()
2. class의 클래스의 생성자 (default함수) 만들기
- def __init__(self): 생성
- main()에 있던 customers = self.do_L()와 index = -1를 지우고 init 함수에 customers와 index 설정해주기
- main() 안에 있는 각 함수에 self.붙여주기
- main() 안에 있는 각 customers와 index에 self.붙여주기
import pickle
import sys
import os
import re
class Customer:
def __init__(self):
self.customers = self.do_L()
self.index = -1
def print_menu(self):
return input('''
다음 중에서 하실 작업의 메뉴를 입력하세요.
I - 고객 정보 입력
P - 이전 고객 정보 조회
C - 현재 고객 정보 조회
N - 다음 고객 정보 조회
U - 현재 고객 정보 수정
D - 현재 고객 정보 삭제
S - 고객 정보 저장
Q - 프로그램 종료
''').upper()
def chk_input_data(self, msg, func, upper=True):
while True:
x = input(msg)
if upper:
x = x.upper()
if func(x):
break
else:
print('잘못 입력하셨습니다. 다시 입력 해 주세요.')
return x
def check_email_addr(self, email_addr):
pattern = re.compile('^[a-zA-Z][a-zA-Z0-9]{3,10}@[a-zA-Z0-9]{2,8}[.][a-zA-Z]{2,5}$')
return pattern.search(email_addr)
def do_I(self, customers, index):
#view 클래스 부분
print('고객정보 입력')
customer = { 'name':'', 'gender': '', 'email': '', 'year': 0 }
customer['name'] = self.chk_input_data('이름을 입력하세요 : ', lambda x: True if len(x) > 2 else False, upper=True)
customer['gender'] = self.chk_input_data('성별 (M/F)를 입력하세요 : ', lambda x: True if x in ('M', 'F') else False)
customer['email'] = self.chk_input_data('이메일 주소를 입력하세요 : ', lambda x: True if self.check_email_addr(x) else False, upper=False)
customer['year'] = self.chk_input_data('출생년도 4자리 입력하세요 : ', lambda x: True if len(x) == 4 and x.isdigit() else False)
#model 클래스 부분
customers.append(customer)
index = len(customers) - 1
return index
def do_P(self, customers, index):
print('이전 고객 정보 조회')
if index <= 0:
print('이전 데이터로 이동 불가.')
print(index)
else:
index -= 1
print(f'{index}번째 고객 정보 입니다.')
print(customers[index])
return index
def do_C(self, customers, index):
print('현재 고객 정보 조회')
print('>>>>>', index)
if index >= -1:
print(f'{index}번째 고객 정보 입니다.')
print(customers[index])
else:
print('입력된 정보가 없습니다. 정보 입력은 I를 선택하세요.')
def do_N(self, customers, index):
print('다음 고객 정보 조회')
if index >= (len(customers) - 1):
print('이후 데이터 이동 불가')
print(index)
else:
index += 1
print(f'{index}번째 고객 정보 입니다.')
print(customers[index])
return index
def do_U(self, customers, index):
print('현재 고객 정보 수정')
customer = { 'name':'', 'gender': '', 'email': '', 'year': 0 }
customer['name'] = self.chk_input_data('수정할 이름을 입력하세요 : ', lambda x: True if len(x) > 2 else False)
customer['gender'] = self.chk_input_data('수정할 성별 (M/F)를 입력하세요 : ', lambda x: True if x in ('M', 'F') else False)
customer['email'] = self.chk_input_data('이메일 주소를 입력하세요 : ', lambda x: True if self.check_email_addr(x) else False, upper=False)
customer['year'] = self.chk_input_data('수정할 출생년도 4자리 입력하세요 : ', lambda x: True if len(x) == 4 and x.isdigit() else False)
print(customer)
customers[index] = customer
def do_D(self, customers, index):
if not customers:
print("고객 정보가 없습니다.")
else:
print(f'현재 고객 정보 {customers[index]["name"]} 삭제')
print('index : ',index)
del customers[index]
if index >= len(customers):
index = len(customers) - 1
return index
def do_S(self, customers):
try:
with open('cust/customers.pickle', 'wb') as fp:
pickle.dump(customers, fp)
except Exception as e:
print('저장하는데에 실패하였습니다.', e)
def do_L(self):
file_path = 'cust/customers.pickle'
if os.path.exists(file_path):
with open(file_path, 'rb') as fp:
return pickle.load(fp)
else:
return list()
#main
def main(self):
# customers = self.do_L()
# index = -1
while True:
menu = self.print_menu()
if menu == 'I':
self.index = self.do_I(self.customers, self.index)
print('index :', self.index)
print('customers : ', self.customers)
elif menu == 'P':
self.index = self.do_P(self.customers, self.index)
elif menu == 'C':
self.do_C(self.customers, self.index)
elif menu == 'N':
self.index = self.do_N(self.customers, self.index)
elif menu == 'U':
self.do_U(self.customers, self.index)
elif menu == 'D':
self.index = self.do_D(self.customers, self.index)
elif menu == 'S':
self.do_S(self.customers)
elif menu == 'Q':
self.do_S(self.customers)
print('저장이 완료되었습니다.')
print('안녕히가세요~')
sys.exit()
else:
print('잘못 입력하셨습니다. 다시 입력 해주세요')
if __name__ == '__main__':
a = Customer()
a.main()
3. CustomerController클래스, CustomerView클래스, CustomerModel클래스 나눠주기 (파일 분리)
- CustomerController클래스 : CustomerView클래스와 CustomerModel클래스를 사용하는 클래스(main)
- CustomerView 클래스 : 사용자 정보 관리하는 부분, 데이터가 보이는 로직이 주로 view
- CustomerModel 클래스 : 데이터나 비즈니스 로직을 처리하는 역할, 데이터를 저장하는 로직이 주로 model
- view와 model에서 각 리턴 값들 정하고 controller에서 사용하기
- customer_mvc_control.py
- CustomerView와 CustomerModel import하기
- self.customer_view, self.customer_model로 뷰, 모델 클래스 호출
- main에서 do_I 정보 가져오기
- 마지막 실행단계에서 클래스 이름 변경해주기
from customer_mvc_view import CustomerView
from customer_mvc_model import CustomerModel
import pickle
import sys
import os
class CustomerController:
def __init__(self):
self.customers = self.do_L()
self.index = -1
#CustomerView클래스 호출
self.customer_view = CustomerView()
#CustomerModel클래스 호출
self.customer_model = CustomerModel()
def print_menu(self):
return input('''
다음 중에서 하실 작업의 메뉴를 입력하세요.
I - 고객 정보 입력
P - 이전 고객 정보 조회
C - 현재 고객 정보 조회
N - 다음 고객 정보 조회
U - 현재 고객 정보 수정
D - 현재 고객 정보 삭제
S - 고객 정보 저장
Q - 프로그램 종료
''').upper()
def do_P(self, customers, index):
print('이전 고객 정보 조회')
if index <= 0:
print('이전 데이터로 이동 불가.')
print(index)
else:
index -= 1
print(f'{index}번째 고객 정보 입니다.')
print(customers[index])
return index
def do_C(self, customers, index):
print('현재 고객 정보 조회')
print('>>>>>', index)
if index >= -1:
print(f'{index}번째 고객 정보 입니다.')
print(customers[index])
else:
print('입력된 정보가 없습니다. 정보 입력은 I를 선택하세요.')
def do_N(self, customers, index):
print('다음 고객 정보 조회')
if index >= (len(customers) - 1):
print('이후 데이터 이동 불가')
print(index)
else:
index += 1
print(f'{index}번째 고객 정보 입니다.')
print(customers[index])
return index
def do_D(self, customers, index):
if not customers:
print("고객 정보가 없습니다.")
else:
print(f'현재 고객 정보 {customers[index]["name"]} 삭제')
print('index : ',index)
del customers[index]
if index >= len(customers):
index = len(customers) - 1
return index
def do_S(self, customers):
try:
with open('cust/customers.pickle', 'wb') as fp:
pickle.dump(customers, fp)
except Exception as e:
print('저장하는데에 실패하였습니다.', e)
def do_L(self):
file_path = 'cust/customers.pickle'
if os.path.exists(file_path):
with open(file_path, 'rb') as fp:
return pickle.load(fp)
else:
return list()
#main
def main(self):
while True:
menu = self.print_menu()
if menu == 'I':
#customer_view 호출(customer정보 가져오기)
customer = self.customer_view.do_I()
#customer_model 호출(뷰의 정보 변수로 넣어서 넘겨주고 customers정보 가져오기)
self.index = self.customer_model.do_I(self.customers, customer)
print('index :', self.index)
print('customers : ', self.customers)
elif menu == 'P':
self.index = self.do_P(self.customers, self.index)
elif menu == 'C':
self.do_C(self.customers, self.index)
elif menu == 'N':
self.index = self.do_N(self.customers, self.index)
elif menu == 'U':
customer = self.customer_view.do_U()
self.index = self.customer_model.do_U(self.customers, customer, self.index)
elif menu == 'D':
self.index = self.do_D(self.customers, self.index)
elif menu == 'S':
self.do_S(self.customers)
elif menu == 'Q':
self.do_S(self.customers)
print('저장이 완료되었습니다.')
print('안녕히가세요~')
sys.exit()
else:
print('잘못 입력하셨습니다. 다시 입력 해주세요')
if __name__ == '__main__':
#클래스 이름 변경
a = CustomerController()
a.main()
- customer_mvc_view.py
- chk_input_data()
- check_email_addr()
- do_I()의 view부분
- do_U()의 view부분
- return값 설정(controller에 넘겨줄 부분)
- return customer
import re
class CustomerView:
#데이터가 보이는 로직이 주로 view
def chk_input_data(self, msg, func, upper=True):
while True:
x = input(msg)
if upper:
x = x.upper()
if func(x):
break
else:
print('잘못 입력하셨습니다. 다시 입력 해 주세요.')
return x
def check_email_addr(self, email_addr):
pattern = re.compile('^[a-zA-Z][a-zA-Z0-9]{3,10}@[a-zA-Z0-9]{2,8}[.][a-zA-Z]{2,5}$')
return pattern.search(email_addr)
def do_I(self):
#view 클래스에 i메소드
print('고객정보 입력')
customer = { 'name':'', 'gender': '', 'email': '', 'year': 0 }
customer['name'] = self.chk_input_data('이름을 입력하세요 : ', lambda x: True if len(x) > 2 else False, upper=True)
customer['gender'] = self.chk_input_data('성별 (M/F)를 입력하세요 : ', lambda x: True if x in ('M', 'F') else False)
customer['email'] = self.chk_input_data('이메일 주소를 입력하세요 : ', lambda x: True if self.check_email_addr(x) else False, upper=False)
customer['year'] = self.chk_input_data('출생년도 4자리 입력하세요 : ', lambda x: True if len(x) == 4 and x.isdigit() else False)
return customer
def do_U(self):
#view
print('현재 고객 정보 수정')
customer = { 'name':'', 'gender': '', 'email': '', 'year': 0 }
customer['name'] = self.chk_input_data('수정할 이름을 입력하세요 : ', lambda x: True if len(x) > 2 else False)
customer['gender'] = self.chk_input_data('수정할 성별 (M/F)를 입력하세요 : ', lambda x: True if x in ('M', 'F') else False)
customer['email'] = self.chk_input_data('이메일 주소를 입력하세요 : ', lambda x: True if self.check_email_addr(x) else False, upper=False)
customer['year'] = self.chk_input_data('수정할 출생년도 4자리 입력하세요 : ', lambda x: True if len(x) == 4 and x.isdigit() else False)
return customer
- customer_mvc_model.py
- do_I에서 model부분
- do_U에서 model부분
- return값 index보내주기
class CustomerModel:
#데이터를 저장하는 로직이 주로 model
def do_I(self, customers, customer):
#model 클래스에 i메소드
customers.append(customer)
index = len(customers) - 1
return index
def do_U(self, customers, customer, index):
print(customer)
customers[index] = customer
return index
여기서는 insert와 update만 mvc로 구분 하였지만 다른 부분도 나누어 보자.
'self.' 하는 이유
- 객체의 속성과 메서드에 접근: self를 통해 현재 객체의 속성에 접근.
예를 들어, self.customers는 현재 객체의 customers 속성을 나타낸다. - 다른 메서드 호출: self를 통해 같은 객체 내의 다른 메서드를 호출.
예를 들어, self.do_L()은 현재 객체의 do_L 메서드를 호출합니다. - 객체의 상태 관리: self를 사용하여 객체의 상태를 관리하고 유지.
객체의 상태는 해당 클래스의 인스턴스 변수들로 표현되며, self를 통해 이들에 접근하고 수정할 수 있다.
모델-뷰-컨트롤러 (MVC)
- Controller 클래스 : 사용자 입력을 받아와 해당 입력에 따라 다양한 작업을 수행하는 역할
모델(Model)과 뷰(View) 객체를 사용하여 데이터와 사용자 인터페이스를 관리 - View 클래스 : 사용자 인터페이스를 관리하고 사용자에게 정보를 표시하는 역할
예를 들어, 사용자로부터 입력을 받는 메서드, 메뉴를 출력하는 메서드, 정보를 표시하는 메서드 등 - Model 클래스 : 데이터나 비즈니스 로직을 처리하는 역할
예를 들어, 고객 정보를 저장하고 관리하는 메서드, 파일에서 데이터를 읽거나 쓰는 메서드, 데이터 유효성 검사 메서드 등
'Back-End > Python' 카테고리의 다른 글
[Python] 파이썬 환경 설정 - anaconda3, jupyter notebook (2) | 2023.11.13 |
---|---|
[Python] 인터프리터와 컴파일러 (3) | 2023.11.13 |
[Python][파이썬] 정규표현식 사용하기 (0) | 2023.11.10 |
[Python][파이썬] 고객 정보 관리 시스템 만들기 실습 5 - class, structure, os라이브러리 (0) | 2023.11.10 |
[Python][파이썬] 고객 정보 관리 시스템 만들기 실습 4 - 고객정보 파일저장, pickle라이브러리 (2) | 2023.11.10 |