파이썬 교재 · 14편 / 27편

파이썬 클래스 입문 — class·__init__·self

데이터와 동작을 한 단위로 묶기. 객체지향의 첫 발걸음.

기초읽는 시간 7분2026-05-13
Student 클래스 정의와 인스턴스 생성, 메서드 호출 코드 화면

학생 30명을 dict 리스트로 처리하다 보면 슬슬 답답해집니다. "학점 계산"·"이름 출력"·"등수 매기기" 함수가 모두 student["name"]·student["score"] 같은 dict 접근을 반복하고, 같은 키를 매번 적는 게 실수의 원천. 학생 한 명을 "데이터(이름·점수) + 동작(학점·인사)" 한 단위로 묶을 수 있다면 코드가 훨씬 정돈됩니다. 그 단위가 클래스(class).

14편을 마치면 ① class 정의 기본 ② __init__ 생성자 ③ self 의 의미 ④ 인스턴스 메서드와 속성 ⑤ dataclass 로 짧게 — 5가지가 손에 익습니다.

class — 데이터와 동작을 한 묶음으로

class Student:
    def __init__(self, name, score):
        self.name = name           # 속성(attribute) 저장
        self.score = score

    def grade(self):                # 인스턴스 메서드
        if self.score >= 90: return "A"
        if self.score >= 80: return "B"
        if self.score >= 70: return "C"
        return "F"

    def greet(self):
        return f"안녕하세요, {self.name} 입니다"

# 인스턴스 만들기 — 클래스를 함수처럼 호출
s1 = Student("준성", 88)
s2 = Student("수민", 92)

s1.grade()              # 'B'
s2.greet()              # '안녕하세요, 수민 입니다'
s1.name                 # '준성' — 속성 직접 접근

구성 요소 네 가지.

  • class 이름 — 관례적으로 PascalCase (단어 첫 글자 대문자). 변수·함수의 snake_case 와 구분
  • __init__ — 인스턴스가 생길 때 호출되는 생성자. 양옆 언더스코어 2개씩 ("던더 메서드")
  • self — 첫 인자에 항상 등장. "지금 만들어진/호출된 이 인스턴스" 를 가리키는 자동 인자
  • self.속성 — 인스턴스에 데이터 저장. 같은 클래스의 다른 인스턴스끼리 독립

self 의 의미 — 가장 헷갈리는 한 단어

입문자가 클래스를 어렵게 느끼는 1번 이유가 self. 다른 언어는 this 라는 키워드로 숨기는데, 파이썬은 명시적으로 적게 만듭니다.

s1 = Student("준성", 88)
s1.grade()
# 위 호출은 사실 이렇게 동작:
# Student.grade(s1)
# → self 자리에 s1 이 자동으로 들어감

s1.grade() 의 안 보이는 첫 인자가 s1 자신. 그래서 메서드 정의에 self 가 반드시 들어가야 하고, 호출할 땐 안 적어요. 한 줄로 정리하면 "점 앞의 객체가 첫 인자로 자동 전달된다".

📌 self 는 키워드가 아니다

실은 단순한 관례. 첫 인자 이름을 this·me 로 적어도 동작합니다(엄청 권장 X). 모두가 self 를 쓰는 건 코드 가독성과 협업을 위한 약속. 본인 코드도 반드시 self 로.

인스턴스 vs 클래스 — 두 단계의 데이터

속성에는 두 종류가 있습니다.

class Student:
    school = "주나이고"        # 클래스 속성 — 모든 인스턴스 공통

    def __init__(self, name):
        self.name = name        # 인스턴스 속성 — 각자 다름

s1 = Student("준성")
s2 = Student("수민")

s1.name == s2.name              # False — 각자 다름
s1.school == s2.school          # True  — 같음
Student.school                  # '주나이고' — 클래스로도 접근

Student.school = "JUNAI"        # 클래스 속성을 바꾸면
s1.school                       # 'JUNAI' — 모든 인스턴스에 반영

클래스 속성은 "모두에게 공통인 사실" — 학교 이름·기본값·카운터 같은 것. 인스턴스 속성은 "각자 다른 값" — 이름·점수·생일.

30명 처리 — 클래스의 진가

students = [
    Student("준성", 88),
    Student("수민", 92),
    Student("지훈", 65),
]

# 학점 일괄 출력
for s in students:
    print(f"{s.name}: {s.grade()}")
# 준성: B
# 수민: A
# 지훈: F

# 정렬 — key 인자로 메서드 결과 사용
ranked = sorted(students, key=lambda s: s.score, reverse=True)
print([s.name for s in ranked])
# ['수민', '준성', '지훈']

같은 일을 dict 로 했을 때보다 호출이 한결 짧고 의미가 명확합니다 — s["name"] 보다 s.name 이 짧고, get_grade(s) 함수보다 s.grade() 가 의도를 더 잘 드러냅니다.

dataclass — 짧게 쓰는 현대식 (3.7+)

속성만 갖고 동작이 적은 클래스는 __init__ 적기가 번잡합니다. dataclass 데코레이터(17편 예고)가 자동으로 만들어줘요.

from dataclasses import dataclass

@dataclass
class Student:
    name: str
    score: int
    school: str = "JUNAI"      # 기본값도 OK

s = Student("준성", 88)
print(s)                        # Student(name='준성', score=88, school='JUNAI')
s.name, s.score                 # 똑같이 접근

__init__·__repr__ 가 자동 생성. 사용자 프로필·설정·DB 행 같이 "주로 데이터를 담는 클래스" 에 최적입니다.

⚠️ 모든 게 클래스여야 하는 건 아니다. 짧은 스크립트는 함수만으로 충분. 같은 데이터에 여러 동작이 묶이거나, 객체를 여러 개 만들어 비교·정렬할 때 클래스가 빛납니다. "왠지 멋있어 보여서" 클래스부터 짜면 코드가 무거워져요.

마무리 — 클래스가 필요한 4가지 신호

  1. 같은 dict 키 조합을 코드 여러 곳에서 만진다 (user["name"]·user["age"]·user["email"]...)
  2. 같은 인자를 받는 함수 3개 이상이 한 그룹으로 모인다
  3. "이 객체에 대해" 라는 표현이 자연스럽다 ("이 학생의 학점", "이 주문의 합계")
  4. 같은 모양의 객체를 여러 개 만들어 리스트로 다룬다 (학생 30명, 상품 100개)

다음 미션 — REPL 에서: ① Book 클래스 (title·author·pages, summary() 메서드) ② 책 3권 만들어 페이지 수 기준 정렬 ③ dataclass 로 같은 걸 다시 짜고 코드 길이 비교.

다음 편 미리보기

15편 — "파이썬 상속 super": 클래스를 확장하는 방법. class Premium(Student) 같은 부모-자식 관계와 super().__init__.

📚 27편 파이썬 교재 시리즈 — 14/27편
← 13편 "파일 읽기·쓰기" · 다음: 15편 "상속·super"

© 2026 주나이테크(주) @JUNAITECH