
※ 클래스, 인스턴스, 속성, 메서드
클래스(Class) : 동일한 목적의 데이터(속성)와 기능(메서드)를 묶은 설계도
인스턴스(Instance) : 클래스로부터 실제로 생성된 개체(실물)
속성(Attribute) : 클래스/인스턴스가 가진 데이터(변수)
메서드(Method) : 클래스/인스턴스가 수행하는 기능(함수)
class Student:
"학생을 표현하는 간단한 클래스"
# 클래스 속성 (모든 인스턴스가 공유)
school = "초등학교"
# 초기화 메서드: 인스턴스 생성 시 자동 호출
def __init__(self, name):
self.name = name # 인스턴스 속성
self.level = 1
# 인스턴스 메서드: 첫 매개변수로 self 필요
def study(self):
print(f"{self.name}는 공부 중입니다.")
# 인스턴스 생성
s1 = Student("지우")
s1.study() # 지우는 공부 중입니다.
print(s1.school) # 초등학교 (클래스 속성 접근)
→ 클래스 = 설계도, 인스턴스 = 실물로 이해하면 편합니다.
※ self 개념과 메서드 호출
self는 메서드를 호출한 바로 그 인스턴스 자신을 가리킵니다. 파이썬은 암묵적으로 self를 넘겨줍니다.
class Echo:
def say(self, msg):
print(f"[{id(self)}] {msg}")
e = Echo()
e.say("hello") # 인스턴스 호출 → self 자동 전달
Echo.say(e, "hello") # 클래스에서 직접 호출 → self를 직접 전달
→ 인스턴스.메서드()는 내부적으로 클래스.메서드(인스턴스) 형태로 실행됩니다.
※ 클래스 속성 vs 인스턴스 속성
클래스 속성은 모든 인스턴스가 공유하고, 인스턴스 속성은 각 인스턴스가 개별 보유합니다.
class Config:
theme = "light" # 클래스 속성 (공유)
def __init__(self, user):
self.user = user # 인스턴스 속성 (개별)
c1 = Config("jiwoo")
c2 = Config("yang")
print(c1.theme, c2.theme) # light light (공유)
Config.theme = "dark"
print(c1.theme, c2.theme) # dark dark
# 인스턴스에서 같은 이름으로 대입하면 '그 인스턴스만' 가려짐(섀도잉)
c1.theme = "custom"
print(c1.theme, c2.theme, Config.theme) # custom dark dark
→ 인스턴스로 클래스 속성을 변경할 수는 없고(그 인스턴스에 새 속성이 생김),
클래스로 변경해야 모두에게 반영됩니다.
※ 메서드의 종류: 인스턴스 / 클래스 / 정적
인스턴스 메서드 : 첫 인자로 self
클래스 메서드 : 첫 인자로 cls, 클래스 레벨 로직에 사용
정적 메서드 : 인자에 self/cls 없음, 유틸성 함수에 사용
class Tool:
version = "1.0"
def inst(self): # 인스턴스 메서드
return f"self id={id(self)}"
@classmethod
def cmethod(cls): # 클래스 메서드
return f"Tool v{cls.version}"
@staticmethod
def smethod(x, y): # 정적 메서드
return x + y
t = Tool()
print(t.inst())
print(Tool.cmethod())
print(Tool.smethod(2, 3))
→ 인스턴스 상태를 쓰지 않는다면 정적/클래스 메서드가 명확합니다.
※ 초기화 메서드와 소멸자
__init__ : 인스턴스 생성 직후 초기화
__del__ : 인스턴스가 소멸될 때 호출(권장 X, 자원 정리는 컨텍스트 매니저 사용 권장)
class FileUser:
def __init__(self, path):
self.path = path
print("열기:", self.path)
def __del__(self):
print("닫기:", self.path)
f = FileUser("note.txt")
→ 파일/네트워크 자원은 with 문(컨텍스트 매니저)로 관리하는 것이 안전합니다.
※ 캡슐화, private, 접근자(getter/setter)
캡슐화는 데이터를 보호하고, 필요한 메서드로만 접근하도록 만드는 원칙입니다.
파이썬의 private 관례: 속성 이름 앞에 __(밑줄 2개)를 붙이면 내부적으로 name-mangling이 적용됩니다.
class Person:
def __init__(self, name="noname"):
self.__name = name # private 느낌 (외부 직접 접근 X)
# getter / setter
def get_name(self):
return self.__name
def set_name(self, name):
if len(name) < 1:
raise ValueError("이름은 비어 있을 수 없음")
self.__name = name
p = Person("지우")
print(p.get_name()) # 지우
p.set_name("양지우")
print(p.get_name()) # 양지우
→ 로깅/검증/부분 접근 등 부가 로직을 접근자에 넣을 수 있습니다.
※ property: 변수처럼 보이지만 함수로 동작
@property를 사용하면 변수처럼 접근하면서 내부적으로 검증/로깅을 수행할 수 있습니다.
class Account:
def __init__(self, owner, balance=0):
self.owner = owner
self.__balance = balance
@property
def balance(self):
print("getter 호출")
return self.__balance
@balance.setter
def balance(self, value):
print("setter 호출")
if value < 0:
raise ValueError("잔액은 음수일 수 없음")
self.__balance = value
acc = Account("jiwoo", 100)
print(acc.balance) # getter 호출 → 100
acc.balance = 300 # setter 호출
print(acc.balance) # 300
→ 기존 수업자료의 property(fget=..., fset=...) 스타일과 동일한 개념입니다.
@property가 더 가독성 좋습니다.
※ __slots__: 인스턴스가 가질 수 있는 속성 제한
동일 클래스라도 임의 속성을 마음대로 추가할 수 있는데, __slots__로 미리 허용 목록을 지정하면
메모리 절약과 오탈자 방지가 가능합니다.
class Point:
__slots__ = ("x", "y") # 이외의 속성은 허용 안 함
def __init__(self, x, y):
self.x = x
self.y = y
p = Point(1, 2)
# p.z = 3 # AttributeError: 'Point' object has no attribute 'z'
※ 상속(Inheritance)
상속은 공통 기능을 상위 클래스에 두고, 하위 클래스가 이를 재사용 + 확장하는 기법입니다.
class Person:
def __init__(self, name="noname"):
self.name = name
def greeting(self):
print(f"안녕, 나는 {self.name}")
class Student(Person): # Person 상속
def __init__(self, name, grade):
super().__init__(name) # 상위 초기화
self.grade = grade
def greeting(self): # 오버라이딩(재정의)
super().greeting() # 상위 기능 유지
print(f"{self.grade}학년 학생이야")
st = Student("지우", 3)
st.greeting()
# 안녕, 나는 지우
# 3학년 학생이야
→ super()를 통해 상위 클래스 기능을 먼저 실행하고 확장하는 패턴이 일반적입니다.
※ 오버라이딩과 다형성(Polymorphism)
오버라이딩 : 상위 클래스의 메서드를 하위에서 같은 이름으로 다시 정의
다형성 : 동일한 메시지(메서드 호출)에 대해 서로 다른 방식으로 반응
class Animal:
def speak(self):
print("...")
class Dog(Animal):
def speak(self):
print("멍멍!")
class Cat(Animal):
def speak(self):
print("야옹!")
# 다형성: 같은 .speak() 호출, 다른 결과
for a in [Dog(), Cat()]:
a.speak()
→ 파이썬은 덕 타이핑(duck typing) 언어입니다. "오리가 꽥꽥 울면 오리"처럼,
speak()가 있으면 Animal 여부와 상관없이 작동합니다.
※ 추상 클래스(Abstract Class)
추상 클래스는 직접 인스턴스화할 수 없고, 하위 클래스에서 반드시 구현해야 하는 추상 메서드를 가집니다.
import abc
class Unit(metaclass=abc.ABCMeta):
@abc.abstractmethod
def attack(self):
pass
class Protoss(Unit):
def attack(self): # 반드시 구현 필요
print("프로토스 공격!")
u = Protoss()
u.attack()
→ 템플릿 메서드 패턴, 팀 내 공통 인터페이스 강제 등에 유용합니다.
※ (참고) 다중 상속 & MRO
여러 클래스를 동시에 상속할 수 있습니다. 메서드 탐색 순서는 MRO(Method Resolution Order)에 따릅니다.
class A:
def run(self): print("A")
class B:
def run(self): print("B")
class C(A, B):
def run(self):
super().run() # A 먼저
super(A, self).run() # A 다음의 B
C().run()
# A
# B
→ 복잡한 다중 상속은 가독성을 해칠 수 있으니, 구성(컴포지션)도 함께 고려하세요.
※ 비교 팁: is vs ==
== : 값이 같은지 비교 / is : 객체 식별자(id)가 같은지(동일 객체인지) 비교
a = [1, 2]; b = [1, 2]
print(a == b) # True (값이 같다)
print(a is b) # False (다른 객체)
'2025 현대오토에버 모빌리티 SW 스쿨(클라우드 2기) > 파이썬 이론' 카테고리의 다른 글
| [Python] 내장 모듈과 표준 라이브러리 활용 (0) | 2025.09.21 |
|---|---|
| [Python] 예외 처리와 디버깅 (0) | 2025.09.21 |
| [Python] 함수(Function) 완벽 이해 (0) | 2025.09.21 |
| [Python] 연산자와 제어문 (0) | 2025.09.21 |
| [Python] 데이터 타입 완벽 정리 (2) – 고급 자료형 (0) | 2025.09.21 |