학습 정리 - enumerate, 문자열의 3가지 표현 방법, 상속 (2025-01-17)

수아·2025년 1월 17일
0

학습 정리

목록 보기
14/51
post-thumbnail

회고 리스트

1. enumerate로 인덱스와 값을 출력하시오.

names = ['홍길동','김현주','윤나은','이지선']

enum_names = enumerate(names)

for i, name in enum_names : 
    print(i, name)
    
# 출력 : 
0 홍길동
1 김현주
2 윤나은
3 이지선

2. enumerate를 사용해 딕셔너리를 생성하시오.

names = ['홍길동','김현주','윤나은','이지선']

enum_names = enumerate(names, 1)		# 1번부터 시작

enum_dict = dict(enum_names)

print(enum_dict)						
# 출력 : {1: '김현주', 2: '윤나은', 3: '이지선', 4: '홍길동'}

3.문자열을 3가지 방식으로 나오도록 하시오.

name = '홍길동'
age = 22

# 1. 표현식 기반 문자열 조합
print("이름 : %s 나이 : %d" %(name, age))

# 2. 메소드 호출 기반 문자열 조합
print("이름 : {} 나이 : {}".format(name, age))

# 3. f-string 기반 (3.6버전부터 제공)
print(f"이름 : {name} 나이 : {age}")

# 출력 : 이름: 홍길동 나이 : 22

4. 아래에서 에러가 나는 이유와 에러가 안 나도록 하시오.

class Simple():
    def seti(self,i):
        self.i = i # 변수 자체를 동적으로 생성한다.
    
    def geti(self):
        return self.i # 에러가 나는 이유
    
s = Simple()
print(s.geti())

i를 주지 않았기 때문에 변수를 동적 할당하지 않았다.
에러가 나지 않도록 하려면 geti 하기 전에 s.seti(10) 같이 i 값을 미리 설정해야 한다.

5. 상속에 대하여 예를 들어 설명해 보시오.

class Animal : 
    def __init__(self, name, color, size) : 
        self.name = name
        self.color = color
        self.size = size

    def eat(self) : 
        print('냠냠')


class Capybara (Animal) : 		# 상속
    def __init__(self, name, color, size, weight) : 
        super().__init__(name, color, size)			# 부모 클래스의 초기화 호출
        self.weight = weight

    def eat(self) : 
        super().eat()								# 부모 클래스의 eat() 호출
        print("맛있당")

capy = Capybara('카피', 'brown', 100, 60)
capy.eat()		# 출력 : 냠냠 맛있다

상속(Inheritance)은 부모 클래스의 속성과 메서드를 자식 클래스가 물려받는 것이다.
자식 클래스는 부모 클래스 기능을 그대로 사용하거나 기능의 재정의(오버라이딩) 할 수 있다.
상속을 통해 코드의 재사용성을 높이고 중복을 줄일 수 있다.

예시에서는 부모 클래스(Animal)에서 동물의 기본 특징과 행동을 정의하고
자식클래스(Capybara)에서 필요에 따라 부모 클래스의 기능(eat)을 변경하거나 확장했다.

6. 단일상속과 다중상속의 차이는?

  • 단일 상속 (Single Inheritance)
    : 자식 클래스가 한 개의 부모 클래스만 상속받는 방식이다.
    : 부모 클래스의 속성과 메서드를 그대로 물려받아 자식 클래스에서 활용하거나 확장한다.
    : 구조가 간단하고 이해하기 쉽고 상속 계층이 단순해서 충돌이나 모호성이 적다.

  • 다중 상속 (Multiple Inheritance)
    : 자식 클래스가 여러 부모 클래스를 상속받는 방식이다.
    : 부모 클래스가 둘 이상이므로 여러 클래스의 속성과 메서드를 물려받는다.
    : 다양한 기능을 조합해서 강력한 클래스를 설계할 수 있다.
    : 하지만 메서드 이름이 겹치거나 상속 순서가 복잡하면 충돌이나 모호성 문제가 발생할 수 있다.

class Animal:
    def move(self):
        print("Animal moves.")

class Bird:
    def fly(self):
        print("Bird flies.")

class Bat(Animal, Bird):  # 다중 상속
    pass

bat = Bat()
bat.move()  # 출력: Animal moves.
bat.fly()   # 출력: Bird flies.

7. 오버라이딩에 대하여 설명하시오.

1) 상속 관계에서만 사용가능하다.
: 부모 클래스에서 메서드를 자식 클래스에서 재정의하는 것이기 때문에 반드시 상속이 전제되어야 한다.

2) 메서드 이름, 매개변수, 반환값이 동일하다.
: 부모 클래스의 메서드와 같은 이름, 매개변수를 사용해야 오버라이딩으로 인식된다.

3) 부모 클래스의 메서드를 호출 가능하다.
: super()를 사용하면 부모 클래스의 원래 메서드 구현을 호출할 수 있다.

4) 다형성의 구현
: 오버라이딩은 다형성을 구현하는데 중요한 역할을 한다.
: 같은 이름의 메서드가 클래스에 따라 다르게 동작하도록 설계 가능하다.

8. HybridCar 클래스를 완성하시오.

class Car:
    def __init__(self,name,color):
        self.name = name
        self.color = color

    def show_info(self):
        print(f'이름: {self.name} 이고 색상은:{self.color}')

hybrid = HybridCar("하이브리드","검정",10)
hybrid.show_info()

# 출력 : 이름: 하이브리드 이고 색상은:검정 / 배터리 용량은: 10

class HybridCar(Car) : 
    def __init__(self, name, color, battery):
        super().__init__(name, color)
        self.battery = battery

    def show_info(self) : 
        super().show_info()
        print(f"배터리 용량은 : {self.battery}")

hybrid = HybridCar("하이브리드","검정",10)
hybrid.show_info()

9. 상속을 활용하여 사각형 삼각형 넓이 구하시오

shape_list = [Rectangle(10,20),Triangle(10,20)]

sum_area = 0
for shape in shape_list:
    sum_area += shape.area()

print(sum_area)

출력: 300

class Shape : 
    def __init__(self, width, height):
        self.width = width
        self.height = height        

    def area(self) : 
        pass

class Rectangle(Shape) : 
    def __init__(self, width, height):
        super().__init__(width, height)

    def area(self) : 
        return self.width * self.height

class Triangle(Shape) : 
    def __init__(self, width, height):
        super().__init__(width, height)

    def area(self) : 
        return self.width * self.height / 2
        
shape_list = [Rectangle(10,20),Triangle(10,20)]

sum_area = 0
for shape in shape_list:
    sum_area += shape.area()

print(sum_area)			# 출력 : 300

10. Animal 을 상속 하여 Dog 를 완성하시오

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        pass

dog = Dog("멍멍이")
print(dog.name) #멍멍이
print(dog.speak()) # 멍멍!

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        pass

class Dog(Animal) : 
    def __init__(self, name):
        super().__init__(name)
    
    def speak(self) : 
        return "멍멍!"
    
dog = Dog("멍멍이")
print(dog.name)         # 출력 : 멍멍이
print(dog.speak())      # 출력 : 멍멍!

11. 연산자 오버로딩을 예를 들어 설명하시오.

# 연산자 오버로딩
class Account : 
    def __init__(self, bal):		# 잔액 초기화
        self.bal = bal

    def __add__(self, money) : 		# + 연산자 오버로딩
        self.bal += money
        
    def __sub__(self, money) :		# - 연산자 오버로딩 
        self.bal -= money
    
    
    # 복합 대입 연산자의 경우 i를 붙여야 한다.
    # 연산 후에 다시 대입하기 때문에 return self가 필수이다.
    
    def __iadd__(self, money) :		# += 연산자 오버로딩      
        self.bal += money
        return self                 # 연산 후 객체 반환

    def __isub__(self, money) :		# -= 연산자 오버로딩
    	self.bal -= money
        return self			

    def __str__(self) :				# 객체를 문자열로 표현 
        return str(self.bal)


my_acc = Account(0)     # 초기 잔액 : 0

my_acc + 100            # 100원 추가
print(my_acc)           # 출력 : 100

my_acc -= 30            # 30원 차감
print(my_acc)           # 출력 : 70

연산자 오버로딩은 기존에 정의된 연산자의 동작을 사용자 정의 클래스에 맞게 재정의하는 것이다.
이를 통해 객체 간의 연산을 기본 자료형처럼 직관적으로 처리할 수 있다.


세줄요약:
1. 상속 = 재사용(reuse) = 부모에 있는 함수및 변수를 써먹을수 있다.
2. 오버라이딩은 자식꺼
3. 메서드 오버라이딩 = 클래스 상속 관계에서 똑같은 함수 이름으로 내용을 달리 하는거


어쩐지 이번에 다시 파이썬 공부를 하면서 f-string을 보고 이런 게 있었나? 싶었다.ㅋㅋㅋ
하다보니까 이게 더 편해서 이거 왜 안 배웠었지?? 했는데 나중에 추가된 버전인 것 같다.

0개의 댓글