CPP를 얼레벌레 하고 넘어가서 OPP에 대한 개념이 모호하게 잡혀있었다.
클래스와 객체, 인스턴스, 메소드와 생성자, 소멸자의 개념을 정리했다.
예시는 프로그래머스의 파이썬 입문 강좌를 참고했다.
self
__new__(cls)
__init__(self)
__str__(self)
super()
여러대의 계산기로 계산을 수행한다고 할 때, 계산기 함수를 여러개를 만들 수도 있지만 클래스를 사용 할 수도 있다.
클래스를 사용하면 함수 여러개를 사용 했을 때와 동일한 효과를 볼 수 있기 때문이다
()
를 붙여 호출할 수 있다. Class()
class Human():
'''인간'''
person1 = Human() # 인스턴스 생성
person2 = Human() # 인스턴스 생성
# 인스턴스를 클래스처럼 사용할 수 있다.
person1.language = '한국어'
person2.language = 'English'
person1.person = '한국인'
person2.person = '인도인'
# 함수 선언
def speak():
print(f'{person.person}은 {person.language}를 사용합니다.')
# 함수를 클래스에 적용 : 메소드 X -> 메소드 사용방법은 하단 참조
Human.speak = speak()
# 사용
# 아래 두 출력값은 같은 형식으로 출력된다.
speak(person1) # 한국인은 한국어를 사용합니다.
person2.speak # 인도인은 English를 사용합니다.
클래스로 만들어진 별개의 프로그램을 객체 object 라고 하는데, 이 객체는 다른 객체의 값에 영향을 받지 않는다.
다시 말해, 객체는 각각 고유한 성격을 가진다.
과자를 여러 개 만들 때, 과자 틀을 클래스에 비유한다면 과자 틀로 만들어진 각각의 과자는 객체라고 할 수 있을 것이다.
# class
class Cookie:
pass
# object
# 클래스의 결과값을 돌려받은 a와 b가 객체다.
a = Cookie()
b = Cookie()
객체와 인스턴스는 어떻게 다른가?
객체는 개념이고 인스턴스는 실체다.
클래스로 만든 객체를 인스턴스라고도 한다. OOP (Object Oriented Programming, 객체 지향 프로그래밍) 에서 객체와 인스턴스는 혼용이 가능하나 인스턴스는 클래스와 함께 사용되는것이 자연스럽다.
객체는 클래스의 인스턴스이므로 실체에 가까운 개념은 인스턴스다. 예를들어, MMORPG 게임에서 던전이라는 클래스가 있다면 객체는 모든 플레이어가 플레이하는 A라는 이름의 던전이고 인스턴스는 플레이어인 내가 직접 플레이하는 던전 A의 복제 (통칭 인던, 인스턴스 던전) 이다.
isinstance(instance, type)
클래스와 인스턴스는 어떤 관계인가?
너와 나는 모두 인간 클래스의 인스턴스이지만 같은 인스턴스는 아니다.
# 예시
list1 = list("instance")
list2 = list("instance")
if list1 == list2: # == 는 값을 비교하는 연산자다.
print('list1과 list2의 값은 같지만'))
if list1 is list2: # is 는 같은 인스턴스인지 확인한다.
print('list1과 list2는 같은 인스턴스다.') # 이 줄은 실행되지 않는다.
else:
print('list1과 list2는 다른 인스턴스다.') # 이 줄은 실행된다.
self
self
이며 인스턴스를 호출할 때 self
를 사용한다.Class_example.method_example()
만 사용하면 된다. Class_example.method_example2(argument_example)
# 메소드를 활용한 클래스 활용 예
class Human():
'''인간'''
# person이라는 인스턴스에 name, weight 변수를 만들어 return하는 함수
def create(name, weight):
person = Human()
person.name = name
person.weight = weight
return person
def eat(self):
self.weight += 0.1
def walk(self):
self.weight -= 0.1
person = Human.create("철수", 60.5)
eat()
# 메소드가 아닌 함수를 호출하려면 person.eat = eat(person)을 선언하고
# eat(person) 또는 person.eat을 호출해야했다.
* Python 에서 특수한 메소드는 메소드를 `__` 언더바 두개로 감싼다.
* Special Method, Magic Method 라고도 부른다.
* Python이 내부적으로 구현한 내장 메소드다.
__new(cls[,...])__
: 객체 생성 함수
__init__()
은 호출되지 않는다.__init__(self[,...])
: 초기화 함수
__new__()
에 의해 인스턴스가 만들어진 후, 호출자에게 돌려주기 위해 호출된다.__new__()
메소드가 인스턴스를 생성하면 __init__()
메소드가 이를 커스터마이징한다. (변수전달 등)__init__()
은 Class에 메모리를 할당하지 않는다.__init__()
메소드가 None
이외의 값을 돌려주면 실행 시간에 TypeError
가 발생된다.self
는 새 인스턴스이며 그 외의 다른 인자를 포함 할 수 있다.__init__
활용 예시
class Human():
'''인간'''
def __init__(self):
print("__init__이 실행되었습니다.")
# 출력
person = Human()
# __init__이 실행되었습니다.
self
활용 예시
class Human():
'''인간'''
def __init__(self, name, weight):
print("__init__이 실행되었습니다.")
print(f"이름은 {name}이고 몸무게는 {weight} 입니다.")
# 출력
person = Human("철수", 60)
# __init__이 실행되었습니다.
# 이름은 철수이고 몸무게는 60입니다.
# 아무것도 하지 않았는데도 init 함수 안의 내용이 실행됨을 확인할 수 있다.
create 함수와 비교
class Human():
'''인간'''
def __init__(self, name, weight):
'''초기화 함수'''
self.name = name
self.weight = weight
# 출력
person = Human ("철수", 60)
print(person.name)
print(person.weight)
# 철수
# 60
# 이전에 사용한 create 메소드
# 인스턴스명인 person이 self로 교체됨을 확인할 수 있다.
class Human():
'''인간'''
# person이라는 인스턴스에 name, weight 변수를 만들어 return하는 함수
def create(name, weight):
person = Human()
person.name = name
person.weight = weight
return person
__str__(self)
: 문자열화 함수__str__
함수를 사용하지 않은 상태에서 객체를 출력하면 <main. ~ object ~> 와 같은 메시지가 출력된다.str()
함수가 자동으로 호출하는 것이 __str__()
이다.# __str__ 예시
class Human():
'''인간'''
def __init__(self, name, weight):
self.name = name
self.weight = weight
def __str__(self):
return f"{name}(몸무게 : {weight}kg)"
person = Human("철수", 60)
# 출력
print(person)
# 철수(몸무게 : 60)
생성자 Constructor
def __init__(self[,...]):
소멸자 Destructor
def __del__(self)
wave(self)
greet()
self.덮어쓰기를원하는메소드()
형식으로 호출한다.person.wave()
def greet(self):
아래에 새로운 작동 방식을 명령한다.super()
super().greet()
super()
함수는 __init__
과 함께 자주 사용된다.super().__init__(name)
# 상속과 오버라이드 예
class Animal(): # 부모 클래스
def __init__(self, name):
self.name = name
def greet(self):
print(f"{self.name} 이/가 인사한다")
class Cow(Animal):
'''소''' # 아무것도 안적으면 에러 발생하므로 주석을 추가한다.
class Human(Animal): # 자식 클래스
def wave(self):
print("손을 흔들다")
def greet(self):
self.wave() # 손을 흔들다.
class Dog(Animal): # 자식 클래스
def __init__ (self, name, emotion): # __init__의 값 사용
super().__init__(name)
self.emotion = emotion
def wag(self):
print(f"{self.emotion} 꼬리를 흔들면서",end=" ") # 목표출력: 꼬리를 흔들면서 인사한다.
def greet(self):
self.wag()
super().greet() # 부모의 greet 메소드도 함께 사용하기 위해 super() 사용
# 출력
cow = Cow("소")
cow.greet() # 소 이/가 인사한다
person = Human("철수")
person.greet() # 손을 흔들다
dog = Dog("강아지","기쁘게")
dog.greet() # 기쁘게 꼬리를 흔들면서 강아지 이/가 인사한다
# 위에서 부모 클래스의 __init__ 값을 빌려온 항목 : 강아지가