공부 기록장
클래스와 객체지향 프로그래밍 본문
객체
문자열, 리스트도 객체다
파이썬의 모든 코드는 객체를 만들고, 동작하게 만드는 내용이다
객체의 본질적인 특징은 보통 문자열의 문자, 리스트의 요소와 같은 상태뿐만 아니라
해당 상태에서 동작하는 메서드를 가지고 있다는 것이다
메서드는 속성 연사자 `.`을 통해 객체에 연결된 함수처럼 호출된다
객체는 항상 연결된 타입이 있는데,
연결된 타입은 type()을 사용해 확인 가능하다
객체는 해당 타입의 `인스턴스`라 부른다
class 문
클래스는 보통 메서드를 만드는 함수의 모음으로 구성된다
인스턴스 메서드는 클래스의 인스턴스에서 동작하는 함수인데,
첫 번째 인수로 클래스의 인스턴스가 전달되고, 관례적으로 self라고 쓴다
(호출 시에 해당 인수는 생략된다)
__init__()
__repr__()
위와 같이 언더바 2개를 앞뒤로 붙인 함수는
스페셜 메서드(special method) 또는 매직 메서드(magic method)이다
해당 메서드들은 인터프리터 런타임에서 특별한 의미가 있다
__init__() 메서드는 새 인스턴스를 생성할 때 상태를 초기화하고
__repr__() 메서드는 객체를 살펴보기 위한 문자열을 반환한다.
__repr__() 메서드는 반드시 정의될 필요는 없지만,
정의하면 대화식 프롬프트에서 디버깅이 간편해지고 객체를 쉽게 알아볼 수 있다
클래스 정의에서는 문서화 문자열과 타입 힌트를 작성할 수 있다
class Account:
'''
간단한 은행 계좌
'''
owner: str
balance: float
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
...
타입 힌트는 서드파티 도구나 IDE에서 유용하게 쓰이고,
특정 고급 프로그래밍 기법에서도 사용하는 `순수 메타 데이터(metadata)`로 필수는 아니다
인스턴스
클래스의 인스턴스는 클래스 객체를 함수처럼 호출하여 생성한다
__init__() 에는 새롭게 생성된 인스턴스 self와 클래스 객체를 호출할 때 함께 제공한 인수가 전달된다
vars() 함수를 사용하여 인스턴스의 변수를 볼 수 있다
(vars() 함수는 변수만 보여주지, 메서드를 표시하지 않는다)
class MyClass:
def __init__(self, name, age):
self.name = name
self.age = age
# 클래스 객체를 함수처럼 호출하여 인스턴스 생성
obj = MyClass("OpenAI", 2)
# vars() 함수를 사용하여 인스턴스의 변수를 출력
print(vars(obj)) # 출력: {'name': 'OpenAI', 'age': 2}
인스턴스는 모두 연결된 타입을 통해 클래스와 링크되어 있다!
속성 접근
인스턴스에서 수행할 수 있는 작업은 크게 3가지이다
속성 가져오기, 속성 설정하기, 속성 삭제하기
파이썬의 모든 것은 제한이 없는 동적 프로세스로,
객체가 생성된 후 생성된 객체에 새로운 속성을 자유로이 추가할 수 있다
class MyClass:
def __init__(self, name):
self.name = name
# 객체 생성
obj = MyClass("OpenAI")
# 속성 가져오기
print(f"Name: {obj.name}") # 출력: Name: OpenAI
# 새로운 속성 추가 및 설정하기
obj.age = 2
print(f"Age: {obj.age}") # 출력: Age: 2
# 기존 속성 변경하기
obj.name = "AI"
print(f"Updated Name: {obj.name}") # 출력: Updated Name: AI
# 속성 삭제하기
del obj.age
# 삭제된 속성 접근 시도
# print(obj.age) # 이 줄을 주석 처리하여 AttributeError를 방지
# 새로운 속성 추가
obj.location = "San Francisco"
print(f"Location: {obj.location}") # 출력: Location: San Francisco
유효 범위 규칙
메서드는 언제나 self를 통해 인스턴스 속성을 참조한다
파이썬의 self 매개변수는 Java의 this 포인터와 같다고 생각하면 된다
다만, 파이썬은 언제나 이를 명시적으로 사용해야 한다
연산자 오버라이딩과 프로토콜
새로운 클래스를 정의할 때, 일반적으로 스페셜 메서드의 일부를 정의한다
사용자 클래스에서 파이썬 연산을 수행할 때에는 언제나 미리 정의된 스페셜 메서드를 사용하도록 한다
상속
상속(inheritance)란 기존 클래스의 동작을 특수화하거나 변경해 새 클래스를 만드는 매커니즘
원본 클래스는 기본 클래스(base class) , 상위 클래스(super class), 부모 클래스(parent class)
새로운 클래스는 파생 클래스(derived class), 자식 클래스(child class), 하위 클래스(subclass) 또는 서브 타입(subtype) 이라 부른다
클래스가 상속으로 생성될 때, 클래스는 기본 클래스가 정의한 속성을 상속 받지만,
파생 클래스는 상속받은 속성을 재정의하고, 자신만의 새로운 속성을 가질 수 있다
특별한 기본 클래스가 없으면 모든 파이썬 객체의 조상 클래스인 object에서 상속받는다
이 클래스는 __str__()와 __repr__() 메서드와 같은 일반 메서드의 기본 구현을 제공한다
파생 클래스는 때에 따라서 원래의 메서드를 호출할 필요가 있는데,
이런 경우에는 super()를 사용하여 명시적으로 호출 가능하다
__init__()을 재정의할 떄, super().__init__()을 사용하여 부모를 초기화하는 것이 자식의 역할이다!
class ParentClass:
def __init__(self, name):
self.name = name
print("ParentClass initialized")
class ChildClass(ParentClass):
def __init__(self, name, age):
super().__init__(name) # ParentClass의 __init__ 메서드를 호출하여 초기화
self.age = age
print("ChildClass initialized")
def display(self):
print(f"Name: {self.name}, Age: {self.age}")
# ChildClass의 인스턴스 생성
obj = ChildClass("OpenAI", 2)
# display 메서드 호출
obj.display()
.
.
.
해당 블로그 글은 '파이써닉한 파이썬을 익히는 간결한 안내서'를 참고하여 작성하였습니다