클래스
관련 정보와 조작 함수(메서드)를 묶어서 관리하는 방식이다.
class
키워드로 정의한다.class Account: def __init__(self, balance): self.balance = balance def deposit(self, money): self.balance += money def inquire(self): print(f"잔액은 {self.balance}원 입니다.") account = Account(8000) account.deposit(1000) account.inquire() shinhan = Account(8000) shinhan.deposit(1000) shinhan.inquire() nonghyup = Account(1200000) nonghyup.inquire() ''' stdout 잔액은 9000원 입니다. 잔액은 9000원 입니다. 잔액은 1200000원 입니다. '''
기본적으로 메서드의 첫 번째 인자로
self
가 들어간다.해당 인스턴스의 참조 변수이며, 다른 언어에서의
this
와 같다.C++의 클래스도 내부적으로는 이런 방식으로 전달된다.
생성자
def __init__(self):
로 정의한다.클래스의 인스턴스를 생성할 때 자동으로 호출된다.
멤버 변수를 정의 및 초기화하는 역할이다.
별도로 구현하지 않으면 기본 생성자가 적용된다.
상속
기존 클래스 정의를 그대로 가져다가 사용하고, 추가 기능도 덧붙일 수 있다.
class 자식클래스명(부모클래스명):
처럼 괄호로 나타낸다.
액세스
파이썬은 정보 은폐 기능이 없다.
- C++로 치면
private
,public
등의 키워드가 없는 것이다.
- C++로 치면
대신 getter/setter로 정보를 보호한다.
@property
- 함수명이 프로퍼티명이 되고, getter 함수로 동작한다.
@프로퍼티명.setter
- 프로퍼티의 setter 함수를 정의한다.
데코레이터(Decorator)
@
(at)으로 시작하는 것
class Date: def __init__(self, month): self.inner_month = month @property def month(self): return self.inner_month @month.setter def month(self, month): if 1 <= month <= 12: self.inner_month = month else: print(Exception("허용 범위 초과")) today = Date(8) today.month = 15 print(today.month) ''' stdout 허용 범위 초과 8 '''
프로퍼티명 = property(getter 함수, setter 함수)
로도 사용할 수 있다.class Date: def __init__(self, month): self.__month = month def getmonth(self): return self.__month def setmonth(self, month): if 1 <= month <= 12: self.__month = month month = property(getmonth, setmonth) today = Date(8) today.month = 15 print(today.month) ''' stdout 8 '''
프라이빗 멤버 변수
멤버 변수 앞에
__
(언더바 2개)를 붙이면 외부에서 바로 접근할 수 없다.today = Date(8) today.month = 15 print(today.month) print(today.__month) # 예외 발생
메서드
클래스 메서드
아직까지 그냥 정의한 메서드는 인스턴스 메서드이다.
반드시 인스턴스를 만든 후 사용할 수 있다.
첫 번째 인자는 인스턴스에 대한 참조인
self
를 관례로 사용하는 것 같다.
클래스 메서드는 인스턴스와 상관없이 존재한다.
- 첫 번째 인자는 클래스에 대한 참조인
cls
를 관례로 사용하는 것 같다.
- 첫 번째 인자는 클래스에 대한 참조인
클래스 멤버 변수
인스턴스와 무관하게 정의되는 멤버 변수이다.
모든 인스턴스가 공유한다.
정적 메서드
클래스 내에 정의되는 일반함수이다.
첫 번째 인자가 정해지지 않는다.
- 클래스 멤버 변수에 접근하려면
클래스명.변수명
형태로 접근하면 된다.
class Car: @staticmethod def hello(): print("오늘도 안전운행 합시다.") print(Car.count) count = 0 def __init__(self, name): self.name = name self.serial = Car.count Car.count += 1 @classmethod def outcount(cls): print(cls.count) def intro(self): print(f"{self.name} ({self.serial})") print(Car.count) pride = Car("프라이드") korando = Car("코란도") Car.outcount() print(Car.count) Car.count = 100 Car.outcount() pride.intro() korando.intro() Car.hello() ''' stdout 0 2 2 100 프라이드 (0) 코란도 (1) 오늘도 안전운행 합시다. 100 '''
- 클래스 멤버 변수에 접근하려면
연산자 메서드
연산자를 재정의할 수 있다.
연산자 별로 함수명이 정해져 있다.
연산자 함수명 == __eq__ != __ne__ < __lt__ > __gt__ <= __le__ >= __ge__ + __add__, __radd__ - __sub__, __rsub__ * __mul__, __rmul__ / __div__, __rdiv__ // __floordiv__, __rfloordiv__ % __mod__, __rmod__ ** __pow__, __rpow__ << __lshift__ >> __rshift__ __str__
- print(객체) 호출 시 해당 객체의 __str__()을 호출한다. 이 함수는 문자열 형태의 값을 반환한다.
__repr__
- 다른 컬렉션에 담겨서 순회당할 때, 다른 함수가 __repr__()을 호출한다.
class Human(): def __init__(self, name, age): self.name = name self.age = age def intro(self): print(f"{self.age}살 {self.name}입니다.") def __str__(self): return f"<Human name: {self.name}, age: {self.age}>" def __repr__(self): return f"<Human name: {self.name}>" kim = Human("김상형", 29) kim.intro() lee = Human("이승우", 45) lee.intro() print(kim) print(lee) li = [kim, lee] print(li) ''' stdout 29살 김상형입니다. 45살 이승우입니다. <Human name: 김상형, age: 29> <Human name: 이승우, age: 45> [<Human name: 김상형>, <Human name: 이승우>] '''