이 튜토리얼은 Python의 핵심 객체지향 기능을 탐구하며 클래스 생성, 인스턴스화, 견고한 코드를 위한 모범 사례를 안내합니다.
동영상: Python 클래스와 객체
Python 객체와 클래스
Python은 근본적으로 객체지향적입니다. 절차적 프로그래밍이 함수에 초점 맞춘다면 OOP는 데이터와 행동을 묶은 객체 중심.
객체는 속성(데이터)과 메서드(함수)의 묶음. 클래스는 객체 구조를 정의하는 청사진.
클래스를 집 설계도라 생각—방, 문, 창문 상세히 기술. 그 설계도로 지어진 각 집이 객체, 즉 인스턴스.
같은 클래스에서 여러 객체 생성 가능. 인스턴스화는 클래스에서 객체 만드는 과정.
Python에서 클래스 정의하기
클래스 정의는 class 키워드로 시작(함수는 def로 시작). 클래스 첫 문자열은 독스트링으로 간결한 설명 제공.
class MyNewClass:
'''This is a docstring. I have created a new class'''
pass
클래스 정의로 속성(데이터나 메서드)용 새 네임스페이스 생성. 이중 언더스코어로 시작하는 특수 속성(__doc__ 등)은 독스트링 같은 메타데이터 보유.
정의되면 클래스 객체 생성돼 속성 접근이나 새 객체 인스턴스화에 사용 가능.
class Person:
"This is a person class"
age = 10
def greet(self):
print('Hello')
# 출력: 10
print(Person.age)
# 출력: <function Person.greet>
print(Person.greet)
# 출력: "This is a person class"
print(Person.__doc__)
출력
10 <function Person.greet at 0x7fc78c6e8160> This is a person class
Python에서 객체 생성하기
클래스는 객체 팩토리 역할. 인스턴스화는 함수 호출과 유사:
>>> harry = Person()
결과 객체 harry가 점 표기법으로 클래스 속성 접근. 클래스 메서드는 인스턴스에서 바인드 메서드(bound method)가 됨.
class Person:
"This is a person class"
age = 10
def greet(self):
print('Hello')
# Person 클래스의 새 객체 생성
harry = Person()
# 출력: <function Person.greet>
print(Person.greet)
# 출력: <bound method Person.greet of <__main__.Person object>>
print(harry.greet)
# 객체의 greet() 메서드 호출
# 출력: Hello
harry.greet()
출력
<function Person.greet at 0x7fd288e4e160> <bound method Person.greet of <__main__.Person object at 0x7fd288e9fa30>> Hello
메서드 정의에 self 파라미터가 있는 점 주목. 인스턴스에서 메서드 호출 시 Python이 자동으로 인스턴스를 첫 인수로 전달해 harry.greet()가 self 명시 없이 실행됨.
관례상 self 사용하나 문법상 어떤 이름도 유효. 이 관례 따르는 게 가독성 높이고 커뮤니티 표준과 일치.
Python 생성자
이중 언더스코어 접두사 특수 메서드들이 특수 역할 수행. __init__ 메서드는 인스턴스화 시 호출돼 인스턴스 상태 초기화하는 생성자 역할.
class ComplexNumber:
def __init__(self, r=0, i=0):
self.real = r
self.imag = i
def get_data(self):
print(f'{self.real}+{self.imag}j')
# ComplexNumber 객체 생성
num1 = ComplexNumber(2, 3)
# get_data() 메서드 호출
# 출력: 2+3j
num1.get_data()
# 다른 ComplexNumber 객체 생성
# 동적 속성 'attr' 추가
num2 = ComplexNumber(5)
num2.attr = 10
# 출력: (5, 0, 10)
print((num2.real, num2.imag, num2.attr))
# 없는 속성 접근 시 에러
print(num1.attr)
출력
2+3j (5, 0, 10) Traceback (most recent call last): File "<string>", line 27, in <module> print(num1.attr) AttributeError: 'ComplexNumber' object has no attribute 'attr'
이 예제는 속성이 개별 인스턴스에 동적으로 추가돼 다른 인스턴스에 영향 없음을 보여줍니다.
속성과 객체 삭제하기
del 문으로 속성 제거. 클래스 메서드나 속성 삭제하면 이후 호출 영향.
>>> num1 = ComplexNumber(2,3)
>>> del num1.imag
>>> num1.get_data()
Traceback (most recent call last):
... AttributeError: 'ComplexNumber' object has no attribute 'imag'
>>> del ComplexNumber.get_data
>>> num1.get_data()
Traceback (most recent call last):
... AttributeError: 'ComplexNumber' object has no attribute 'get_data'
객체 자체도 삭제 가능. 참조 제거로 이름 해제; 다른 참조 없으면 가비지 컬렉터가 자동 회수.
>>> c1 = ComplexNumber(1,3)
>>> del c1
>>> c1
Traceback (most recent call last):
... NameError: name 'c1' is not defined
Python에서 메모리 관리는 참조 카운팅과 순환 가비지 컬렉터가 처리해 효율적 자원 정리 보장.