파이썬

Python Class 심화

클래스 기반 메소드 심화

- Class Method

- Instance Method

- Static Method

- 3가지 메소드 활용 실습

# Chapter02-01
# 객체 지향 프로그래밍(OOP) -> 코드의 재사용, 코드 중복 방지, 유지보수, 대형 프로젝트
# 규모가 큰 프로젝트 -> 함수 중심 -> 데이터 방대 -> 복잡
# 클래스 중심 -> 데이터 중심 -> 객체로 관리

# 일반적인 코딩: 비효율적임
# 차량 1
car_company_1 = 'Ferrari'
car_detail_1 = [
    {'color': 'White'},
    {'horsepower': 400},
    {'price': 8000}
]

# 차량 2
car_company_2 = 'Bmw'
car_detail_2 = [
    {'color': 'Black'},
    {'horsepower': 270},
    {'price': 5000}
]

# 차량 3
car_company_3 = 'Audi'
car_detail_3 = [
    {'color': 'Silver'},
    {'horsepower': 300},
    {'price': 6000}
]

# 리스트 구조: 관리하기 불편하고, 인덱스 접근 시 실수 가능성 있고 삭제도 불편함
car_company_list = ['Ferrari', 'Bmw', 'Audi']
car_detail_list = [
        {'color': 'White','horsepower': 400,'price': 8000},
        {'color': 'Black','horsepower': 270,'price': 5000},
        {'color': 'Silver', 'horsepower': 300,'price': 6000}

]

# 딕셔너리 구조: 코드 반복 지속, 중첩 문제(키), 키 조회 예외 처리 등
car_dicts = [
    {'car_company': 'Ferrari', 'car_detail': {'color': 'White','horsepower': 400,'price': 8000}},
    {'car_company': 'Bmw', 'car_detail': {'color': 'Black','horsepower': 270,'price': 5000}},
    {'car_company': 'Audi', 'car_detail': {'color': 'Silver', 'horsepower': 300,'price': 6000}}
]

# 클래스 구조: 구조 설계 후 재사용성 증가, 코드 반복 최소화, 메소드 활용
class Car():
    def __init__(self, company, details):
        self._company = company
        self._details = details
    
    def __str__(self): # 사용자 레벨에서 내용을 확인하고 싶을 때
        return 'str : {} - {}'.format(self._company, self._details)
    
    def __repr__(self): # 개발자 레벨에서 객체 정보를 알고 싶을 때 사용
        return 'repr : {} - {}'.format(self._company, self._details)

car1 = Car('Ferrari', {'color': 'White','horsepower': 400,'price': 8000})
car2 = Car('BMW',  {'color': 'Black','horsepower': 270,'price': 5000})
car3 = Car('Audi', {'color': 'Silver', 'horsepower': 300,'price': 6000})

print(car1)
print(car2)
print(car3)

print(car1.__dict__) # 클래스 안의 속성값들을 알려줌
print(car2.__dict__)
print(car3.__dict__)
# Chapter02-02
# 객체 지향 프로그래밍(OOP) -> 코드의 재사용, 코드 중복 방지, 유지보수, 대형 프로젝트
# 규모가 큰 프로젝트 -> 함수 중심 -> 데이터 방대 -> 복잡
# 클래스 중심 -> 데이터 중심 -> 객체로 관리

# 클래스 구조: 구조 설계 후 재사용성 증가, 코드 반복 최소화, 메소드 활용
class Car():
    """
    Car class
    Author: Lee
    Data: 2023.12.05
    """

    # 클래스 변수(모든 인스턴스가 공유)
    car_conut = 0


    def __init__(self, company, details):
        self._company = company
        self._details = details
    
    def __str__(self): # 사용자 레벨에서 내용을 확인하고 싶을 때
        return 'str : {} - {}'.format(self._company, self._details)
    
    def __repr__(self): # 개발자 레벨에서 객체 정보를 알고 싶을 때 사용
        return 'repr : {} - {}'.format(self._company, self._details)
    
    def detail_info(self):
        print('Current ID : {}'.format(id(self)))
        print('Car Detail Info : {} {}'.format(self._company, self._details.get('price')))
    
car1 = Car('Ferrari', {'color': 'White','horsepower': 400,'price': 8000})
car2 = Car('BMW',  {'color': 'Black','horsepower': 270,'price': 5000})
car3 = Car('Audi', {'color': 'Silver', 'horsepower': 300,'price': 6000})

# dir: 해당 인스턴스가 가지고 있는 모든 attribute들을 리스트 형태로 반환, dict: 딕셔너리 형태로 모든 값들을 key와 value 형태로 보여줌
print(dir(car1))
print(car1.__dict__) 

# Doctring: 클래스 상세 내용 보여줌
print(Car.__doc__)

# 실행
car1.detail_info()

# 인스턴스 네임스페이스에 없으면 상위에서 검색
# 즉, 동일한 이름으로 변수 생성 가능(인스턴스 검색 후 -> 상위(클래스 변수, 부모클래스 변수))​
# Chapter02-03
# 객체 지향 프로그래밍(OOP) -> 코드의 재사용, 코드 중복 방지, 유지보수, 대형 프로젝트
# 규모가 큰 프로젝트 -> 함수 중심 -> 데이터 방대 -> 복잡
# 클래스 중심 -> 데이터 중심 -> 객체로 관리

class Car():
    """
    Car class
    Author: Lee
    Data: 2023.12.05
    Description: Class, Static, Instance Method
    """

    # 클래스 변수(모든 인스턴스가 공유)
    price_per_raise = 1.0

    def __init__(self, company, details):
        self._company = company
        self._details = details
    
    def __str__(self): # 사용자 레벨에서 내용을 확인하고 싶을 때
        return 'str : {} - {}'.format(self._company, self._details)
    
    def __repr__(self): # 개발자 레벨에서 객체 정보를 알고 싶을 때 사용
        return 'repr : {} - {}'.format(self._company, self._details)
    
    # Instance Method
    # Self: 객체의 고유한 속성값을 사용
    def detail_info(self):
        print('Current ID : {}'.format(id(self)))
        print('Car Detail Info : {} {}'.format(self._company, self._details.get('price')))

    # Instance Method
    def get_price(self):
        return 'Before Car Price -> company: {}, price : {}'.format(self._company, self._details.get('price'))
    
    # Instance Method
    def get_price_culc(self):
        return 'After Car Price -> company: {}, price : {}'.format(self._company, self._details.get('price') * Car.price_per_raise)

    # Class Method: 클래스를 받음
    @classmethod
    def raise_price(cls, per):
        if per <= 1:
            print('Please Enter 1 Or More')
            return
        cls.price_per_raise = per
        print('Succeed! price increased')
    
    # Static Method: 파라미터를 받지 않음. 그래서 유연함
    @staticmethod
    def is_bmw(inst):
        if inst._company == 'BMW':
            return 'OK! This car is {}'.format(inst._company)
        return 'Sorry. This car is not BMW.'



# self 의미    
car1 = Car('Ferrari', {'color': 'White','horsepower': 400,'price': 8000})
car2 = Car('BMW',  {'color': 'Black','horsepower': 270,'price': 5000})

# 전체정보
car1.detail_info()
car2.detail_info()

# 가격정보(직접 접근) 
print(car1._details.get('price'))
print(car2._details['price'])

# 가격정보(인상 전)
print(car1.get_price())
print(car2.get_price())

# 가격 인상(클래스 메소드 미사용)
Car.price_per_raise = 1.4

# 가격정보(인상 후)
print(car1.get_price_culc())
print(car2.get_price_culc())

# -------------------------------

# 가격정보(인상 전)
print(car1.get_price())
print(car2.get_price())

# 가격 인상(클래스 메소드 사용. 클래스 변수를 핸들링할 때는 클래스 메소드 사용을 권장)
Car.raise_price(2.0)


# 가격정보(인상 후)
print(car1.get_price_culc())
print(car2.get_price_culc())

# --------------------------------
# 인스턴스로 호출(static)
print(car1.is_bmw(car1))
print(car2.is_bmw(car2))
# 클래스로 호출(static)
print(Car.is_bmw(car1))
print(Car.is_bmw(car2)) # 유연해서 이렇게 해도 됨