🟡 Python 5차 강의 🟡
✅ 클래스
🔰 class ?
- 클래스(Class) : 객체(Object)를 만들기 위한 설계도나 틀. 속성(특징, 데이터)과 메서드(기능, 함수)로 구성
- 객체(Object) : 클래스를 통해 만들어낸 실제 사물(Instance : 인스턴스). 클래스를 붕어빵 틀이라고 한다면, 객체는 그 틀로 찍어낸 각각의 붕어빵.
- 인스턴스(Instance) : 특정 클래스로부터 생성된 객체를 그 클래스의 인스턴스라 부름
- 클래스 이름은 관례적으로 단어의 첫 글자를 대문자로 시작 (예: MyClass).
- 클래스 내부 요소
- 인스턴스 변수(instance variable), 클래스 변수(class variable)
- 인스턴스 메서드(instance method), 클래스 메서드(class method), 정적 메서드(static method)
class 클래스이름:
# 클래스 본문
# 속성(변수)과 메서드(함수)를 정의
__init__ 메서드 (생성자)
- 인스턴스가 생성될 때 자동으로 호출되는 메서드로, 주로 인스턴스 변수를 초기화하는 데 사용
- 생성자(Constructor) 라고도 함
class Person:
def __init__(self, name, age):
self.name = name # 인스턴스 변수
self.age = age
def introduce(self):
print(f"안녕하세요, 제 이름은 {self.name}이고, 나이는 {self.age}살입니다.")
⇒
Person 클래스는 __init__ 메서드를 통해 name과 age라는 인스턴스 변수를 설정하고, introduce() 메서드를 통해 자기 소개를 할 수 있게 함
객체 생성
클래스를 정의한 후에는 클래스를 호출하는 형식으로 객체를 생성
p1 = Person("Alice", 25)
p2 = Person("Bob", 30)
p1.introduce() # "안녕하세요, 제 이름은 Alice이고, 나이는 25살입니다."
p2.introduce() # "안녕하세요, 제 이름은 Bob이고, 나이는 30살입니다."
⇒
p1과 p2는 모두 Person 클래스의 인스턴스로, 각각 다른 속성을 가질 수 있음
변수
- 인스턴스 변수 (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
⇒
wheels는 클래스 변수로 Car의 모든 인스턴스에 동일한 값(4개)을 갖음.
반면 color는 인스턴스별로 다른 값(red, blue)을 갖음
🔰 메서드
인스턴스 메서드 (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를 받지 않음
- 주로 클래스나 인스턴스 변수에 접근할 필요가 없는 경우 사용
- 데코레이터 @staticmethod를 사용
class MathUtils:
@staticmethod
def add(a, b):
return a + b
result = MathUtils.add(3, 5)
print(result) # 8
🔰 특징
캡슐화
파이썬은 언어 차원에서 public, private 접근 제어자를 명시적으로 제공하지 않지만, 관례적으로 변수나 메서드 앞에 언더스코어(_)를 붙여 내부적으로 사용함을 암시
- _변수명: 해당 변수는 내부적 용도로 사용되는 것을 암시 (개발자간 약속)
- __변수명: 이름 장식(name mangling)을 통해 외부에서 접근하기 어렵게 만듦
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.__balance = balance # 이 변수는 직접 접근하기 어렵게 함
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
acc = BankAccount("Alice", 1000)
print(acc.get_balance()) # 1000
acc.deposit(500)
print(acc.get_balance()) # 1500
acc.withdraw(2000) # "잔고 부족"
print(acc.get_balance()) # 1500
# acc.__balance 는 직접 접근 불가능 (AttributeError 발생)
⇒
이와 같이 캡슐화를 통해 내부 데이터는 메서드로만 접근 가능하게 하여 데이터 무결성을 보장
상속 (Inheritance)
기존 클래스를 재사용하여 새로운 클래스를 만들 수 있게 하는 기능
상속을 통해 기존 클래스(부모 클래스 또는 슈퍼 클래스)의 속성과 메서드를 자식 클래스(서브 클래스)에서 물려받을 수 있고, 필요하다면 확장 또는 수정할 수 있음
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print("동물이 소리를 냅니다.")
class Dog(Animal): # Animal 클래스를 상속
def speak(self):
print(f"{self.name}가 멍멍 짖습니다.")
dog = Dog("멍멍이")
dog.speak() # "멍멍이가 멍멍 짖습니다."
⇒
Dog 클래스는 Animal 클래스를 상속하여 name 속성과 speak() 메서드를 물려받음
그리고 Dog 클래스에서 speak() 메서드를 재정의(오버라이딩)하여 특정한 동작을 구현할 수 있음
다형성 (Polymorphism)과 오버라이딩 (Overriding)
- 다형성(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 인스턴스 -> "동물 소리"
⇒
같은 speak() 메서드를 호출하지만, 객체의 타입에 따라 다른 결과를 얻는 것을 볼 수 있음
🔰
실제 예제: 학생 관리 시스템
class Student:
def __init__(self, name, student_id):
self.name = name
self.student_id = student_id
self.scores = []
def add_score(self, score):
self.scores.append(score)
def get_average(self):
if not self.scores:
return 0
return sum(self.scores) / len(self.scores)
def introduce(self):
print(f"이름: {self.name}, 학번: {self.student_id}, 평균점수: {self.get_average()}")
# 사용 예시
s1 = Student("Alice", "20230001")
s1.add_score(90)
s1.add_score(85)
s1.add_score(100)
s2 = Student("Bob", "20230002")
s2.add_score(70)
s2.add_score(75)
s1.introduce() # 이름: Alice, 학번: 20230001, 평균점수: 91.666...
s2.introduce() # 이름: Bob, 학번: 20230002, 평균점수: 72.5
정리
- 클래스는 객체(인스턴스)를 만들기 위한 설계도이며, OOP의 핵심 개념
- 인스턴스 변수, 클래스 변수를 통해 데이터를 관리하고, 인스턴스 메서드, 클래스 메서드, 정적 메서드를 통해 기능을 구현
- __init__ 메서드(생성자)를 통해 인스턴스 생성 시 초기화 과정을 수행할 수 있음
- 접근 제어(명시적 키워드는 없지만 언더스코어 컨벤션), 캡슐화, 상속, 다형성 등을 통해 코드 재사용성과 유연성을 극대화
- 클래스를 통해 관련된 데이터와 기능을 논리적 단위로 묶어내면 큰 규모의 프로그램을 더 체계적이고 유지 관리하기 용이
🔰 과제
실습 01
개인과제 - 필수
더보기
# %%
문제 1 : 짝수의 합 구하기
📌 요구 지식: 리스트, 반복문, 조건문
배경:
장바구니 금액 중에서 짝수 금액만 골라 합산해야 하는 간단 로직을 연습합니다.
목표:
정수 리스트에서 짝수만 골라 합계를 반환하는 함수를 작성하세요.
데이터:
# 예시 데이터
numbers = [3000, 7000, 2000, 8000, 5000, 10000, 11000]
def sum_even(numbers):
"""
numbers: 정수 리스트
반환값: 짝수들의 합 (int)
"""
# 여기에 코드를 작성하세요
return
# 예시 실행 (제출 시 주석 처리)
# print(sum_even(numbers)) # 46000
# %%
# numbers = [3000, 7000, 2000, 8000, 5000, 10000, 11000]
def sum_even(numbers):
total = 0
for i in numbers:
if i % 2 == 0:
total += i
return total
# print(sum_even(numbers)) # 46000
# %%
문제 2 : 문장 속 단어 개수 세기
📌 요구 지식: 문자열, split(), 반복문(선택)
배경:
리포트에서 단어 수를 집계해야 할 때 기본적으로 공백 기준으로 단어를 셉니다. 연속된 공백도 잘 처리되어야 합니다.
목표:
문자열에서 공백 기준 단어 수를 반환하는 함수를 작성하세요.
데이터:
# 예시 데이터
text = " hello world python "
def count_words(text):
"""
text: 문자열
반환값: 단어 개수 (int)
"""
# 여기에 코드를 작성하세요
return
# 예시 실행 (제출 시 주석 처리)
# print(count_words(text)) # 3
# %%
# text = " hello world python "
def count_words(text):
blank = text.split()
word_cnt = len(blank)
return word_cnt
# print(count_words(text)) # 3
# %%
문제 3 : 문자열 속 숫자 합 구하기
📌 요구 지식: 문자열, 반복문, 조건문
배경:
로그나 코드 문자열 속에 섞여 있는 숫자 문자(0-9) 들만 뽑아 간단히 합계를 낼 때가 있습니다.
목표:
문자열에서 숫자 문자(0-9)만 찾아 모두 더한 합을 반환하세요.
(연속된 숫자라도 각 자리수를 더합니다. 예: "23" → 2+3=5)
데이터:
# ex1. 반환 값 -> 10
text = "a1b23c004"
# ex2. 반환 값 -> 0
text = "Hello"
# ex3. 반환 값 -> 18
text = "9-9=0"
def sum_of_digits(text):
"""
문자열에서 숫자 문자(0-9)만 찾아 모두 더해 반환.
예) "a1b23c004" -> 1+2+3+0+0+4 = 10
"""
# 여기에 코드를 작성하세요
return
# 예시 실행 (제출 시 주석 처리)
# print(sum_of_digits(text)) # 10
# %%
# text1 = "a1b23c004"
# text2 = "Hello"
# text3 = "9-9=0"
def sum_of_digits(text):
num = str([0,1,2,3,4,5,6,7,8,9])
blank = []
for i in text:
if i in num:
blank += i
chan = list(map(int, blank))
sumnum = 0
for i in chan:
sumnum += i
return sumnum
# print(sum_of_digits(text1))
# print(sum_of_digits(text2))
# print(sum_of_digits(text3))
# %%
문제 4 : 합격/불합격 집계하기
📌 요구 지식:
배경:
학생 점수 데이터에서 기준 점수 이상은 합격, 미만은 불합격으로 분류합니다.
목표:
{이름: 점수} 딕셔너리를 받아 합격/불합격 인원 수를 딕셔너리로 반환하세요. (기본 합격 기준 60점)
데이터:
scores = {"Alice": 85, "Bob": 52, "Chris": 60, "Dana": 59}
def grade_pass_fail(scores, threshold=60):
"""
반환값 예: {'pass': 2, 'fail': 2}
"""
# 여기에 코드를 작성하세요
return
# 예시 실행 (제출 시 주석 처리)
# print(grade_pass_fail(scores)) # {'pass': 2, 'fail': 2}
# %%
# scores = {"Alice": 85, "Bob": 52, "Chris": 60, "Dana": 59}
def grade_pass_fail(scores, threshold=60):
new_score = {i: ("pass" if j >= 60 else "fail")for i, j in scores.items()}
new_list = list(new_score.values())
val1 = new_list.count("pass")
val2 = new_list.count("fail")
new_dict = {"pass" : val1, "fail" : val2}
return new_dict
# print(grade_pass_fail(scores))
# %%
문제 5 : 입고 반영한 재고 합치기
📌 요구 지식:
배경:
현재 재고와 입고 수량을 합쳐 최신 재고를 만듭니다.
목표:
current와 arrival 두 딕셔너리를 받아 상품별 총 재고 딕셔너리를 반환하세요.
데이터:
current = {"apple": 5, "banana": 2, "milk": 1}
arrival = {"banana": 3, "bread": 4, "milk": 2}
def merge_inventory(current, arrival):
"""
반환값 예: {'apple': 5, 'banana': 5, 'milk': 3, 'bread': 4}
"""
# 여기에 코드를 작성하세요
return
# 예시 실행 (제출 시 주석 처리)
# print(merge_inventory(current, arrival))
# {'apple': 5, 'banana': 5, 'milk': 3, 'bread': 4}
# %%
# current = {"apple": 5, "banana": 2, "milk": 1}
# arrival = {"banana": 3, "bread": 4, "milk": 2}
def merge_inventory(current, arrival):
merge_dict = {}
for k, v in current.items():
merge_dict.setdefault(k, []).append(v)
for k, v in arrival.items():
merge_dict.setdefault(k, []).append(v)
# print(merge_dict)
# {'apple': [5], 'banana': [2, 3], 'milk': [1, 2], 'bread': [4]}
for i, j in merge_dict.items():
merge_dict[i] = sum(j)
return merge_dict
# print(merge_inventory(current, arrival))
# {'apple': 5, 'banana': 5, 'milk': 3, 'bread': 4}
# %%
문제 6 : 두 수의 합(인덱스 반환)
📌 요구 지식: 딕셔너리, 반복문, 조건문
배경:
목표 합을 만드는 두 원소의 인덱스를 빠르게 찾는 패턴 연습입니다.
목표:
정수 리스트 nums와 정수 target이 주어질 때, 합이 target이 되는 서로 다른 두 인덱스를 (i, j)로 반환하세요. (없으면 (-1, -1))
데이터:
# ex1. 반환 값 (0,1)
nums = [2, 7, 11, 15]
target = 9
# ex2. 반환 값 (-1, -1)
nums = [2, 7, 11, 15]
target = 10
def two_sum(nums, target):
"""
반환값 예: (0, 1) # nums[0] + nums[1] = 9
"""
# 여기에 코드를 작성하세요
return
# 예시 실행 (제출 시 주석 처리)
# print(two_sum(nums, target))
# %%
'Sparta > Theory' 카테고리의 다른 글
| [250829] 스파르타코딩 본캠프 19일차 (1) - pandas 02 (0) | 2025.08.29 |
|---|---|
| [250828] 스파르타코딩 본캠프 18일차 (1) - pandas 01 (2) | 2025.08.28 |
| [250822] 스파르타코딩 본캠프 14일차 (1) - Python 04 - dict, def (3) | 2025.08.22 |
| [250821] 스파르타코딩 본캠프 13일차 (1) - Python 03 - list (2) | 2025.08.21 |
| [250820] 스파르타코딩 본캠프 12일차 (1) - Python 02 - if, for (0) | 2025.08.20 |