기본

class Account:
    # 클래스 변수 (자바 static)
    bank_name = "MyBank"

    # 생성자
    def __init__(self, owner, balance=0):
        self.owner = owner        # 인스턴스 변수 (self 필수)
        self.balance = balance

    # 인스턴스 메서드 (self 항상 첫 인자)
    def deposit(self, amount):
        self.balance += amount

    def __str__(self):            # toString()
        return f"{self.owner}: {self.balance}"

acc = Account("Kim", 1000)        # new 키워드 없음
acc.deposit(500)
print(acc)                        # __str__ 호출 → "Kim: 1500"
print(Account.bank_name)          # "MyBank"

캡슐화 (접근 제어가 없음, 컨벤션으로 관리)

따로 접근 제어가 없어서, 네이밍 규칙으로 표현

class Sample:
		def __init__(self):
				self.public = 1      # 공개
				self._protected = 2  # _ : "내부용 (관례)"
				self.__private = 3   # __ : name mangling (실제로 접근 어려움)

private 추가 설명:

Python에서 접근에 대한 제어를 해주는 것, 관례가 아님.

다만, “완전한 private”인지? → 그건 아님

_클래스__변수명 형태로 쓰면 접근이 가능, 파이썬이 내부적으로 바꿔서 저장한 것일뿐, 이게 “진짜 이름”

접근 예시:

class Sample:
		def __init__(self):
				self.__private = 3

s = Sample()

print(s.__private)         # 접근 제어, **AttributeError**
print(s._Sample__private)  # **"3", <- 진짜 이름으로 접근**

property (getter/setter)

자바의 getXxx/setXxx 대신 @property 사용

class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def radius(self):              # getter
        return self._radius

    @radius.setter
    def radius(self, value):       # setter
        if value < 0:
            raise ValueError("음수 불가")
        self._radius = value

    @property
    def area(self):                # 계산된 프로퍼티
        return 3.14 * self._radius ** 2

c = Circle(5)
c.radius          # 5 (메서드인데 () 없이 호출)
c.radius = 10     # setter 동작
c.area            # 314.0
# c.radius = -1   # ValueError

주요 매직 메서드 (던더 메서드)

class Vector:
    def __init__(self, x, y):
        self.x, self.y = x, y
    def __add__(self, other):       # + 연산자 오버로딩
        return Vector(self.x+other.x, self.y+other.y)
    def __eq__(self, other):        # == (equals)
        return self.x==other.x and self.y==other.y
    def __len__(self):              # len() 동작
        return 2
    def __repr__(self):             # 디버깅용 표현

        return f"Vector({self.x}, {self.y})"

v = Vector(1, 2) + Vector(3, 4)     # Vector(4, 6)

dataclass (자바 record / Lombok 같은 것)

from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int
    **label: str = "origin"      # 기본값**

p = Point(1, 2)
print(p)              # Point(x=1, y=2, label='origin') - __repr__ 자동
Point(1,2) == Point(1,2)       # True - __eq__ 자동