Python - class

김기훈·2025년 10월 26일

Python

목록 보기
5/8

class

__init__

  • 객체가 만들어질 때 자동으로 실행되어 객체의 초기 상태를 설정하는 메서드
    • 미사용시에는 객체 속성을 직접 지정해야 하므로 코드가 지저분하고 실수하기 쉬움
  • 장점
    • 필수 속성을 강제하고 유효성 검증을 걸 수 있음
    • 인스턴스마다 독립적인 상태를 보장해서 공유 버그(특히 리스트/딕셔너리 같은 가변 객체)들을 예방

__init__ 없는 경우

# 1. 기본구조

                          class 클래스 이름:
                              def 매서드(self): # self : 초기화
                                  코드
class UserNoInit:
    def greet(self):
        return f"안녕하세요, 저는 {self.name}입니다."  # name이 있다고 가정…

u = UserNoInit()
# u.name = "기훈"  # ← 이거를 깜빡하면
print(u.greet())
# AttributeError: 'UserNoInit' object has no attribute 'name'

__init__ 있는 경우

# 1. 기본구조

class 클래스이름:
    def __init__(self):
        self.속성 = 값
        
# 2. 기본구조2
class 클래스이름:
    def __init__(self, 매개변수1, 매개변수2):
        self.속성1 = 매개변수1
        self.속성2 = 매개변수2
# 예시 1
class UserInit:
    def __init__(self, name, age):
        if not name:
            raise ValueError("이름은 비어 있을 수 없습니다.")
        if age <= 0:
            raise ValueError("나이는 1살 이상이어야 합니다.")
        self.name = name
        self.age = age

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

u = UserInit("기훈", 25)
print(u.greet())

# 예시 2
class Person:
    def __init__(self, name, age, address):
        self.hello = '안녕하세요.'
        self.name = name
        self.age = age
        self.address = address

    def greeting(self):
        print('{0} 저는 {1}입니다.'.format(self.hello, self.name))

maria = Person('마리아', 20, '서울시 서초구 반포동') # 인스턴스 생성
maria.greeting()    # 안녕하세요. 저는 마리아입니다.

print('이름:', maria.name)       # 마리아
print('나이:', maria.age)        # 20
print('주소:', maria.address)    # 서울시 서초구 반포동

인스턴스별 독립 상태의 차이

# __init__ 없이 클래스 변수 사용 → 모든 인스턴스가 리스트 공유(버그)
class CartNoInit:
    items = []  # 클래스 변수(공유됨)

c1 = CartNoInit()
c2 = CartNoInit()

c1.items.append("사과")
print("c1:", c1.items)  # ['사과']
print("c2:", c2.items)  # ['사과']  ← 원치 않게 공유됨!

# __init__에서 인스턴스 변수로 초기화 → 서로 독립
class CartInit:
    def __init__(self):
        self.items = []  # 인스턴스마다 새 리스트

c1 = CartInit()
c2 = CartInit()

c1.items.append("사과")
print("c1:", c1.items)  # ['사과']
print("c2:", c2.items)  # []  ← 독립적

클래스 상속

  • 부모 클래스(Parent, Superclass)의 속성과 메서드를
    • 자식 클래스(Child, Subclass)가 그대로 물려받아 사용할 수 있는 기능
# 1. 부모 클래스 정의
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        print(f"안녕하세요, 저는 {self.name}이고 {self.age}살입니다.")

# 2. 자식 클래스 정의(부모 클래스 상속)
class Student(Person):  # Person을 상속받음
    def __init__(self, name, age, school):
        super().__init__(name, age)  # ⭐️ 부모(Person)의 __init__ 불러오기
        self.school = school

    def study(self):
        print(f"{self.name}은(는) {self.school}에서 공부 중입니다.")

# 출력 

# 부모 클래스 사용
p1 = Person("기훈", 25)
p1.introduce() # 안녕하세요, 저는 기훈이고 25살입니다.

# 자식 클래스 사용
s1 = Student("민수", 18, "OZ 코딩스쿨")
s1.introduce()  # 부모의 메서드 사용 가능
# 안녕하세요, 저는 민수이고 18살입니다.
s1.study()      # 자식만의 메서드
# 민수은(는) OZ 코딩스쿨에서 공부 중입니다.
  • super().__init__(name, age)
    • Person의 init이 실행되어 name과 age를 초기화
      • Student("기훈", 25, "OZ코딩스쿨") 이 값이 들어가면
      • 그중 name, age는 super().init(name, age)로 부모에게 전달
      • 부모가 self.name, self.age를 설정
  • def init(self, school):
    • 이러면 self.name, self.age가 설정되지 않아서 Student("OZ")에는 name이 아예 존재X

오버라이딩(Overriding)

  • 부모 메서드를 자식이 같은 이름으로 다시 정의해서 동작을 바꿀 수도 있다.
# 1. 부모 클래스 정의
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        print(f"안녕하세요, 저는 {self.name}이고 {self.age}살입니다.")

# 2. 자식 클래스 정의(오버라이딩)
class Student(Person):
    def introduce(self):  # 부모의 introduce()를 덮어씀
    print(f"저는 학생 {self.name}이고, 나이는 {self.age}살이에요!")
        
# 3. 출력
s1 = Student("민수", 18)
s1.introduce() # 저는 학생 민수이고, 나이는 18살이에요!

profile
안녕하세요.

0개의 댓글