-
02-4. 클래스와 예외처리파이썬 2023. 8. 28. 15:05
summary
- function
* docstring
* scope : 전역, 지역 : global
* inner function : 함수 안에 함수를 선언
* lambda function : 간략한 함수를 한 줄의 코드로 작성
* decorator : 특정 기능을 데코레이터 함수로 만들어 함수에 특정 기능을 적용하는 방법
1.Class : 클래스
- 변수와 함수를 묶어 놓은 개념
- 클래스 선언
* 변수와 함수를 클래스 안에서 선언
- 클래스를 객체로 만들어서 클래스 안에 선언된 변수와 함수를 사용1.1.기본 클래스
1.1.1.클래스 선언
class Account: loan = 0 deposit = 0 def save(self, money): self.deposit += money print("현재 계좌 잔액 :{}원".format(self.deposit)) def withdraw(self, money): self.deposit -= money print("인출 금액은 {}원. 현재 계좌 잔액은 {}원".format(money, self.deposit)) def debt(self, d_money): self.deposit += d_money self.credit_debt = d_money + self.loan return -int(self.credit_debt)
acc = Account() acc
-><__main__.Account at 0x7fe4c1d78f10>
acc.loan
->0
1.1.2.객체지향
- 실제 세계를 코드에 반영해서 개발하는 방법
- 여러 명의 개발자가 코드를 효율적으로 작성해서 프로젝트를 완성시키기 위한 방법
- 설계도 작성(class) -> 실제 물건(object)
- 사용자 정의 데이터 타입acc2 = Account()
acc2.loan = 100_000 # _는 쉼표와 같은 역할(없어도 됨) acc2.loan
->100000
acc2.debt(50_000)
->-150000
acc2.deposit
->50000
1.1.3.생성자
- 클래스의 인스턴스 객체가 생성될 때 자동으로 호출되는 메소드
- 변수(재료)를 추가할 때 사용됨class Account: def __init__(self): # 웬만하면 생성자를 넣어서 실행하 self.loan = 0 self.deposit = 0 print("개설 완료") def save(self, money): self.deposit += money print("현재 계좌 잔액 :{}원".format(self.deposit)) def withdraw(self, money): self.deposit -= money print("인출 금액은 {}원. 현재 계좌 잔액은 {}원".format(money, self.deposit)) def debt(self, d_money): self.deposit += d_money self.credit_debt = d_money + self.loan return -int(self.credit_debt)
acc3 = Account()
->개설 완료
acc3.loan
->0
acc3.deposit
->0
acc3.loan = 500_000 acc3.loan
->500000
acc3.debt(500_000)
->-1000000
1.1.4.소멸자
- 객체가 사라질 때 자동으로 호출되는 함수
class Account: def __init__(self): # 웬만하면 생성자를 넣어서 실행하 self.loan = 0 self.deposit = 0 print("개설 완료") def save(self, money): self.deposit += money print("현재 계좌 잔액 :{}원".format(self.deposit)) def withdraw(self, money): self.deposit -= money print("인출 금액은 {}원. 현재 계좌 잔액은 {}원".format(money, self.deposit)) def debt(self, d_money): self.deposit += d_money self.credit_debt = d_money + self.loan return -int(self.credit_debt) def __del__(self): print("계좌 해지 완료!")
acc4 = Account()
->개설 완료
del acc4
->계좌 해지 완료!
acc4
->『NameError: name 'acc4' is not defined』
1.2.상속
- 클래스의 기능을 가져다가 기능을 수정하거나 추가할 때 사용하는 방법
- 클래스가 가지고 있는 멤버나 메소드를 상속받는 클래스가 모두 사용
- 상속을 해주는 클래스 : 부모 클래스 또는 슈퍼 클래스
- 상속을 받는 클래스 : 자식 클래스 또는 서브 클래스1.2.1.부모 클래스(슈퍼 클래스)로 상속받기
class Account: def __init__(self): # 웬만하면 생성자를 넣어서 실행하 self.loan = 0 self.deposit = 0 print("개설 완료") def save(self, money): self.deposit += money print("현재 계좌 잔액 :{}원".format(self.deposit)) def withdraw(self, money): self.deposit -= money print("인출 금액은 {}원. 현재 계좌 잔액은 {}원".format(money, self.deposit)) def debt(self, d_money): self.deposit += d_money self.credit_debt = d_money + self.loan return -int(self.credit_debt) def __del__(self): print("계좌 해지 완료!")
class Stock(Account): # 자식 클래스 이름(상속받을 주체) pass # 나중에 채워 넣기 위해 사용하는 오류 방지 구문
stock = Stock()
->개설 완료
1.2.2.overriding
- 부모로부터 상속받은 클래스의 기능들을 수정하거나 대체
class Stock(Account): def stock_trade(self, buy, sell): self.deposit -= buy self.deposit +=sell if buy and not sell: print("매수 금액 {}원. 현재 계좌 잔액 {}원".format(buy, self.deposit)) else: print("매도 금액 {}원. 현재 계좌 잔액 {}원".format(sell, self.deposit))
stock = Stock()
->개설 완료
stock.stock_trade(100_000,0)
->매수 금액 100000원. 현재 계좌 잔액 -100000원
stock.save(500_000)
->현재 계좌 잔액 :400000원
class Employee: mileage = 0 rate = round(1/15, 2) # 1/15를 소수점 2번째자리로 반올림 def __init__(self, first, last, salary): print("!!입사 축하!!") self.first = first self.last = last self.salary = salary self.id = first.lower() + last.lower() + "@deepnoid.com" self.mileage = 100_000 def save_mileage(self, point): self.mileage += int(point) + self.salary * self.rate print("추가 포인트 : {}점, 누적 마일리지 {}점".format(point, self.mileage))
emp = Employee("gildong", "hong", 1_000)
->!!입사 축하!!
emp.save_mileage(10_000)
->추가 포인트 : 10000점, 누적 마일리지 110070.0점
emp.rate
->0.07
class Employee: mileage = 0 rate = round(1/15, 2) # 1/15를 소수점 2번째자리로 반올림 def __init__(self, first, last, salary): print("!!입사 축하!!") self.first = first self.last = last self.salary = salary self.id = first.lower() + last.lower() + "@deepnoid.com" self.mileage = 100_000 def save_mileage(self, point): self.mileage += int(point) + self.salary * self.rate print("추가 포인트 : {}점, 누적 마일리지 {}점".format(point, self.mileage))
emp2 = Employee("yeounghee", "kim", 1_000)
->!!입사 축하!!
emp2.rate
->0.07
emp2.rate = 0.7 emp2.save_mileage(10_000)
->추가 포인트 : 10000점, 누적 마일리지 110700.0점
class Employee: mileage = 0 rate = round(1/15, 2) # 1/15를 소수점 2번째자리로 반올림 def __init__(self, first, last, salary): print("!!입사 축하!!") self.first = first self.last = last self.salary = salary self.id = first.lower() + last.lower() + "@deepnoid.com" self.mileage = 100_000 def save_mileage(self, point): self.mileage += int(point) + self.salary * Employee.rate print("추가 포인트 : {}점, 누적 마일리지 {}점".format(point, self.mileage)) em3 = Employee("sara", "L", 1_000)
->!!입사 축하!!
em3.rate
->0.07
em3.rate = 0.7 em3.rate
->0.7
em3.save_mileage(10_000) # Employee.rate엔 변함이 없다
->추가 포인트 : 10000점, 누적 마일리지 110070.0점
1.2.3.mangling
- 클래스 변수 안에 접근할 수 없도록 설정하는 방법
- 변수명 앞에 __를 붙여서 사용class Employee: mileage = 0 rate = round(1/15, 2) # 1/15를 소수점 2번째자리로 반올림 def __init__(self, first, last, salary): print("!!입사 축하!!") self.first = first self.last = last self.salary = salary self.id = first.lower() + last.lower() + "@deepnoid.com" self.mileage = 100_000 self.__rate = round(1/15,2) def save_mileage(self, point): self.mileage += int(point) + self.salary * self.__rate print("추가 포인트 : {}점, 누적 마일리지 {}점".format(point, self.mileage)) emp4 = Employee("data", "L", 1_000)
->!!입사 축하!!
emp4.rate
->0.07
emp4.save_mileage(10_000)
->추가 포인트 : 10000점, 누적 마일리지 110070.0점
emp4.__rate = 0.7 emp4.__rate
->0.7
emp4.save_mileage(10_000) # Employee.rate가 사실상 의미 없음
->추가 포인트 : 10000점, 누적 마일리지 130210.0점
1.3.super()
- 부모 클래스에서 사용된 함수의 코드를 받아서 자식(서브) 클래스의 함수에서 재사용할 때 사용
class A: def plus(self): code1 class B(A): def minus(self): code1 # super().plus() code2
class Phone: def __init__(self, function=None): self.name = function print("{} phone 구매 완료".format(self.name)) def calling(self): print("calling")
class CameraPhone(Phone): def __init__(self, function=None): super().__init__(function) def camera(self): print("camera select")
ph = Phone()
->None phone 구매 완료
ph.calling()
->calling
cam = CameraPhone("Camera")
->Camera phone 구매 완료
cam.camera()
->camera select
class WebPhone(CameraPhone): def __init__(self, function=None): super().__init__(function) def web(self): print("web browser select")
web = WebPhone("web")
->web phone 구매 완료
web.web()
->web browser select
1.4.class 다중 상속
class Plus: def plu(self, a,b): return a+b class Sub: def sub(self, a,b): return a-b
class Calc(Plus, Sub): # 겹치는 변수나 코드가 있을 경우, pass # 변경이 될 수 있기 때문에 왼쪽에 있는 클래스가 최상위 슈퍼 클래스가 됨 # 순서 중요!
calc=Calc()
calc.sub(1,2)
->-1
calc.plu(1,2)
->3
1.5.class의 getter, setter
- 객체의 내부 변수에 접근할 때 특정 로직을 거쳐서 접근시키는 방법
- 제약조건을 만들어서 접근 가능 여부를 만들 때 사용class User: def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name def setter(self, first_name): # 클래스 객체 내에 들어갈 때, 변경/생성을 하려면 무조건 이 메소드를 거치게 만듦 if len(first_name) >= 1: self.first_name = first_name else: print("error") def getter(self): print("getter") return self.first_name[0].upper() + self.first_name[1:].lower() name = property(getter, setter)
user1 = User("andy", "Lee")
user1.name
->getter
'Andy'user1.name = "john"
user1.name=""
->error
user1.name
->getter
'John'
1.6.is a & has a
- 클래스를 선언하는 방법
- A is a B
* A는 B이다. 상속을 이용해서 클래스를 만드는 방법
- A has a B
* A는 B를 가진다. A가 B객체를 가지고 클래스를 만드는 방법# is a class Person: def __init__(self, name, email): self.name = name self.email = email class UserInfo(Person): def info(self): print(self.name, self.email)
user = UserInfo("andy", "andy@gmail.com")
user.info() # 상속을 받으면 상속자도 상속하는 것을 알고 있다
->andy andy@gmail.com
# has a class Name: def __init__(self, name): self.name_str = name class Email: def __init__(self, email): self.email_str = email
class User: def __init__(self, name_obj, email_obj): self.name = name_obj self.email = email_obj def info(self): print(name.name_str, email.email_str)
name = Name("andy") email = Email("andy@gmail.com") user2 = User(name, email)
user2.info()
->andy andy@gmail.com
2.예외처리
- 코드를 실행 중에 에러가 발생한 경우 에러를 처리하는 방법
- 예외 상황이 발생하면 코드 진행이 중단되므로 계속 진행할 수 있도록 선언2.1.try exception
try: 문제가 없을 시 실행할 코드 except: 문제 발생(예외상황) 시 실행할 코드
def divide(): a,b = tuple(input("Insert Numbers : ").split(" ")) return int(a)/int(b)
divide()
->Insert Numbers : 10 0
오류 위치『ZeroDivisionError: division by zero』
print("Start") divide() print("Done")
->Start
Insert Numbers : 10 0오류 위치『ZeroDivisionError: division by zero』
def divide2(): a,b = tuple(input("insert numbers : ").split(" ")) try: return int(a)/int(b) except: print("나눗셈 실행 불가")
print("Start") divide2() print("Done")
->Start
insert numbers : 10 0
나눗셈 실행 불가
Done2.2.try except else
- except가 실행되지 않으면 else의 실행문이 마지막에 출력
print("start") num = input("set range") try: res = sum(range(int(num)+1)) except: print("잘못 입력하셨습니다^^") else: print("result:", res) print("Done!")
->start
set range : 10
result: 55
Done!print("start") num = input("set range") try: res = sum(range(int(num)+1)) except: print("잘못 입력하셨습니다^^") else: print("result:", res) print("Done!")
->tart
set range : 십
잘못 입력하셨습니다^^
Done!2.3.try except finally
- except 발생 유무와 상관없이 finally 구문은 실행
def divide(): a,b = tuple(input("insert numbers : ").split(" ")) try: return int(a)/int(b) except: print("연산 수행 불가") finally: print("연산 종료")
print("Start") divide()
->Start
insert numbers : 10 5
연산 종료
2.0def divide(): a,b = tuple(input("insert numbers : ").split(" ")) try: return int(a)/int(b) except ZeroDivisionError: return "0으로는 나눌 수 없습니다"
divide()
->insert numbers : 10 0
'0으로는 나눌 수 없습니다'2.5.설정되어 있는 Exception 오류만 출력
try: print(AI) except Exception as e: # Exception 내용만 가져옴(비추천) -> else 사용하는거 추천 print(e)
->name 'AI' is not defined
AI
->『NameError: name 'AI' is not defined』
2.6.사용자 정의 예외처리
- python은 정상으로 인식할 수 있으나 코드를 작성하는 작성자 기준에서 오류라고 판단되는 부분을 예외처리
class LowNumber(Exception): def __str__(self): return "Number greater than 10"
def input_number(num): if num<=10: raise LowNumber() # raise : LowNumber로 설정한 예외를 발생시킴 print(num)
input_number(8)
->
(오류 위치)『LowNumber: Number greater than 10』
Magic(Special) Method
- compare
* __eq__: ==
* __ne__: !=
* __lt__: <
- calculate
* __add__: +
* __sub__: -
- __repr__: 객체의 내용을 출력(개발자용)
- __str__: 객체의 내용을 출력"test" == "test"
->True
"test".__eq__("test")
->True
(1).__add__(2)
->3
class Txt: def __init__(self, txt): self.txt = txt def __eq__(self,txt_obj): return self.txt.lower() == txt_obj.txt.lower() def __repr__(self): return "Txt(txt={})".format(self.txt) def __str__(self): return self.txt
t1 = Txt("python") t2 = Txt("Python") t3 = t1
t1 == t2, t1 == t3, t2 == t3
->(True, True, True)
t1
->Txt(txt=python)
print(t1)
->python
후반에 많이 사용할 것이기 때문에 연습 많이 하자
'파이썬' 카테고리의 다른 글
02-3. 함수 (0) 2023.08.27 02-2.조건문과 반복문 (0) 2023.08.27 02-1. 파이썬 기초 (0) 2023.08.21