Python 공부

클래스, 생성자, 캡슐화, 상속, 오버라이딩, 매직 메서드

myun0506 2026. 1. 14. 18:13

 

- 함수만 쓸 때 vs 클래스를 쓸 때

  • 함수만 쓰면: 데이터랑 기능이 흩어져서 사람이 기억해야 하는 코드
  • 클래스 쓰면: 현실 세계처럼 물건 단위로 정리된 코드

- __init__ 생성자

  • 인스턴스가 생성될 때 자동으로 호출되는 메서드
  • 생성될 때 호출된다고 해서 생성자(constructor)라고도 불림

- 인스턴스 변수 (instance variable)

  • 각 객체마다 별도로 관리되는 변수
  • self.name, self.age와 같이 self를 통해 참조하는 변수
  • 각각 인스턴스 마다 각각 값을 가질 수 있음

- 클래스 변수 (class variable)

  • 클래스로부터 만들어진 모든 인스턴스가 공유하는 변수
  • 클래스 블록 내에서 self 없이 바로 변수를 정의하면 클래스 변수로 설정됨
class Car:
    wheels = 4  # 클래스 변수: 모든 Car 인스턴스는 바퀴가 4개
    def __init__(self, color):
        self.color = color  # 인스턴스 변수: 각 차마다 색이 다를 수 있음

car1 = Car("red")
car2 = Car("blue")

print(car1.color)  # "red" (car1만의 인스턴스 변수)
print(car2.color)  # "blue" (car2만의 인스턴스 변수)

print(car1.wheels) # 4 (클래스 변수는 모든 객체가 공유)
print(car2.wheels) # 4
  • car1.wheels = 3 를 하면
    • car1에만 새로운 인스턴스 변수를 만드는 것
    • Car.wheels 는 그대로 4임

- 인스턴스 메서드 (Instance Method)

  • 첫 번째 매개변수로 self 받음
  • 각 인스턴스에 대해서 동작하며, 인스턴스 변수를 다루는 데 주로 사용함
class Person:
    def __init__(self, name):
        self.name = name

    def say_hello(self): #인스턴스 메서드
        print(f"Hello, my name is {self.name}")

person1 = Person("alice")
person1.say_hello()

 

- 클래스 메서드 (Class Method)

  • 첫 번째 매개변수로 cls 받음 (self 대신 cls 키워드 사용)
  • 데코레이터 @classmethod 사용
  • 클래스 자체를 인자로 받음
  • 활용: 클래스 변수를 다루는 상황 / 새로운 인스턴스를 생성하는 메서드 등을 정의
class Person:
    count = 0

    def __init__(self, name):
        self.name = name
        Person.count += 1

    @classmethod
    def how_many(cls):
        print(f"지금까지 {cls.count}명이 만들어졌습니다.")

p1 = Person("Alice")
p2 = Person("Bob")
Person.how_many()  # "지금까지 2명이 만들어졌습니다."

 

- 정적 메서드 (Static Method)

  • 첫 번째 매개 변수로 self나 cls 받지 않음
  • 사실 클래스에 굳이 소속될 필요 없음. but '분류상' 틀에 넣어야 깔끔해서 넣는 것.
    (주로 클래스나 인스턴스 변수에 접근할 필요가 없는 경우)
  • 데코레이터 @staticmethod 사용
class MathUtils:
    @staticmethod
    def add(a, b):
        return a + b

result = MathUtils.add(3, 5)
print(result)  # 8

 

- 매직 메서드 (Magic Methods)

  • 파이썬 객체가 '파이썬 답게' 동작하게 만드는 특수 메서드들
  • 종류
    • __init__ : 객체 생성 시 초기화 (생성자)
    • __str__: str() 함수나 print() 호출 시 사용자에게 보여줄 문자열 정의
    • __repr__: 개발자가 디버깅 용도로 객체를 확인할 때 표현되는 문자열 정의
    • __gt__, __lt__: 객체 간의 크기 비교 (>,<) 로직 정의 

 

- 접근 지정자와 캡슐화

  • Java나 C++의 접근 지정자(Public, Protected, Private)와 달리 파이썬에서는 안더스코어를 붙여 사용함
구분 Java / C++ (키워드 방식) Python (언더스코어 방식) 의미
Public public int age; self.age 누구나 접근 가능 (기본값)
Protected  protected int age; self._age [관례] 클래스 내부와 상속 관계에서만 쓰자고 약속함
Private private int age; self.__age [강제성 있음] 이름 변형을 통해 외부 접근을 막음

 

  • _variable (Weak Internal Use) 
    • 문법적으로는 Public과 똑같음. 밖에서 호출해도 에러 안남
    • '이건 이 클래스 내부 구현을 위한거니까, 밖에서 직접 수정하면 코드가 꼬일 수 있어.'라고 경고를 주는 것
  • __variable (Strong Private)
    • "이 변수는 이 클래스 내에서만 쓰겠다. 상속 받은 자식 클래스 조차도 함부로 못 건드리게 하겠다."
      • 자식 클래스에게 공유하고 싶다면 _ 하나만 쓰기!
    • Name Mangling이 일어남
      • self.__password라고 선언하면, 파이썬은 내부적으로 이름을 _ClassName__password로 바꿔버림
      • 외부에서 acc.__password라고 치면 '그런 이름은 없다'는 AttributeError 발생함
class BankAccount:
  def __init__(self, owner, balance, password):
    self.owner = owner
    self.__balance = balance # 이 변수는 직접 접근하기 어렵게 함
    self.__password = password

  def deposit(self,amount):
    self.__balance += amount

  def withdraw(self, amount):
    if self.__balance >= amount:
      self.__balance -= amount
    else:
      print("잔고 부족")
  
  def get_balance(self):
    return self.__balance
  
  def get_password(self):
    return self.__password 
  
  def change_password(self,pw):
    self.__password = pw
  
acc = BankAccount("Alice",1000,12345)
print(acc.get_balance())
acc.deposit(500)
print(acc.get_balance())
acc.withdraw(2000)
print(acc.get_balance())
print(acc.get_password())
acc.change_password(54321)
print(acc.get_password())
print(acc.owner)
print(acc._BankAccount__password) # name mangling
  • Name Mangling과 파이썬의 철학
    • 파이썬은 강제성보다는 관례 (Convention) 를 중시함.
    • 접근을 물리적으로 막는 비용보다, 개발자가 실수로 부모 클래스의 변수를 덮어쓰는 (Shadowing) 것을 방지하는 데 초점을 맞춘 것
    • '우리는 모두 성인이다'라는 말은 내부 구조를 건드려서 발생하는 책임은 그것을 호출한 개발자에게 있다는 책임의 분산과 신뢰를 의미함1.

- 프로퍼티 공부

 

https://blog.naver.com/codeitofficial/221684462326

 

쉽게 배우는 파이썬 문법 - 프로퍼티(Property) 1편

안녕하세요, 코드잇입니다. 이번 시간에는 파이썬에서 사용되는 프로퍼티(Property)라는 기능을 배워볼게...

blog.naver.com

https://blog.naver.com/codeitofficial/221695196435

 

쉽게 배우는 파이썬 문법 - 프로퍼티(Property) 2편

안녕하세요, 코드잇입니다. 오늘은 지난 시간에 이어 파이썬의 프로퍼티를 계속 공부해보겠습니다. 지난 시...

blog.naver.com

https://blog.naver.com/codeitofficial/221701646124

 

쉽게 배우는 파이썬 문법 - 프로퍼티(Property) 3편

안녕하세요, 코드잇입니다. 오늘은 지난 시간에 이어 파이썬의 프로퍼티에 대해서 알려드리도록 하겠습니다...

blog.naver.com

 

- self의 본질

  • 파이썬에서 self는 인스턴스 자신을 가리키는 바인딩 매개변수
  • name = name과 같이 작성하면 단순히 함수 내부의 지역 변수에 값을 담았다가 버리는 행위!
  • self.name이라고 써야만 힙(Heap) 메모리에 위치한 해당 객체의 공간에 데이터가 저장되는 것

 

- 상속 (Inheritance)

  • 기존 클래스를 재사용하여 새로운 클래스를 만들 수 있게 하는 기능
  • 상속을 통해 기존 클래스(부모 클래스 또는 슈퍼 클래스)의 변수 & 메서드를
    • 자식 클래스(서브 클래스)에서 물려 받을 수 있음
  • 필요하다면 물려받은걸 확장 또는 수정도 할 수 있음

- 다형성 (Polymorphism) & 오버라이딩 (Overriding)

  • 다형성
    • 같은 메서드 이름이 다양한 클래스에서 다른 형태로 동작할 수 있음을 의미
  • 오버라이딩
    • 자식 클래스에서 부모 클래스의 메서드를 재정의하는 것
class Animal:
    def speak(self):
        print("동물 소리")

class Cat(Animal):
    def speak(self):
        print("야옹")

class Dog(Animal):
    def speak(self):
        print("멍멍")

animals = [Cat(), Dog(), Animal()]
for a in animals:
    a.speak()
    # Cat 인스턴스 -> "야옹"
    # Dog 인스턴스 -> "멍멍"
    # Animal 인스턴스 -> "동물 소리"

 

 

- 실습 문제 1

class Point:
  def __init__(self, x, y):
    self.x = x
    self.y = y
  
  def move(self,dx,dy):
    self.x += dx
    self.y += dy
    return self

  def show(self):
    print(f"Point({self.x}, {self.y})")
  
p = Point(1,2)
p.move(2,3).show()

 

  • move 메서드에 return self 를 추가하여
    • move 의 결과값을 변수에 따로 저장할 필요 없이 
    • 한 줄로 p.move(2,3).show() 작성