본문 바로가기
관리자

Programming-[Backend]/Python

파이썬 중급 - 1. 클래스와 메서드

728x90
반응형

1. 클래스

클래스를 사용하는 이유는 같은 변수나 메서드를 반복해서 작성할 필요없이 하나의 객체로 만들어서 다른 객체와의 상호작용을 편리하게 하기 위함이다.

 

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.__dict__)
print(car2.__dict__)
print(car3.__dict__)

 

 

str 메서드와 repr 메서드의 차이

https://shoark7.github.io/programming/python/difference-between-__repr__-vs-__str__#2b

str은 각 자료형들을 ‘문자열로 변환하여’ 출력하는데 목적이 있고, repr는 객체를 사람이 읽을 수 있도록 '문자 형태로 표현'하라는데에 그 목적이 있다.

>>> a = 1
>>> b = '가'
>>> c = [1, 2, 3, 4, 5]

>>> print(a, b, c)
# 1 가 [1, 2, 3, 4, 5]

 

위 코드가 가능한 것은 a, b, c가 속하는 각 객체인 int, str, list 타입이 모두 str 메서드를 구현하여 str으로 변환할 수 있도록 되어있기 때문이다. print 메서드가 각 원소의 __str__을 호출하여 str타입으로 변환 후 출력하였다.

class A:
    def __str__(self):
        return 'str method is called'

    def __repr__(self):
        return 'repr method is called'

>>> a = A()

>>> str(a)  # 1.
>>> a  # 2.

# Look at here!
>>> print(a)  # 3.

'str method is called' # 1.
repr method is called  # 2.

# Look at here!
str method is called   # 3.

 

 

기본 매직 메서드

  • __dict__ : field 및 각 값 정보
  • __dir__ : 메타 정보
  • is는 인스턴스의 주소값을 비교한다. 인스턴스의 주소값은 id() 메서드로 확인할 수 있다.
  • __class__ : 인스턴스가 어떤 클래스인지 알려준다.
  • __doc__ : 클래스 뒤에 쓰면 class 바로 밑에 있는 주석문을 호출한다.

 

따라서 주석은 class 정의문 밑에 주로 단다(아래 예시 코드를 참고하자).

만약 메서드 단위의 주석문을 호출하고 싶다면 ‘클래스.__init__.__doc__’ 으로 호출하면 된다. 이렇게 정의한 메서드의 def문 바로 밑에 주석을 두면 그 매직 메서드의 __doc__을 호출할 때 해당 주석문이 호출된다.

이외에도 사칙 연산 등에 사용되는 add, sub, mul, bool, ge, le 등이 있다.

 

 

클래스 더 알아보기

class Car():
    """
    Car Class
    Author : Kim
    Date : 2019.11.08
		Description : 클래스에 대한 주석은 여기에 단다.
    """

    # 클래스 변수
    car_count = 0

    def __init__(self, company, details):
			"""
			메서드에 대한 주석은 여기에 단다.
			"""
        self._company = company
        self._details = details
        Car.car_count += 1

    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')))

    def __del__(self):
        Car.car_count -= 1

 

init 내부에 작성하는 변수는 인스턴스 변수이고, 그 외부이자 class 안에 적는 변수는 클래스 변수이다. ⇒ 클래스 변수는 모든 인스턴스가 공유한다.

  • 클래스 변수는 dict 메서드로 조회되지 않는다. dir()로는 조회된다.
  • 인스턴스 변수 앞에는 underbar(_)를 붙여서 private 변수임을 표시한다. 다만 파이썬은 compiler가 없으므로 이것을 강제하는 것은 아니고, 개발자끼리의 약속 정도를 의미한다. 클래스 변수는 이름 앞에 underbar를 붙이지 않고 public으로 둔다.

 

del

del 메서드는 생성된 인스턴스를 메모리에서 지운다.

 

 

인스턴스 검색 → 상위(클래스 변수, 부모 클래스 변수)로 검색

같은 이름으로 인스턴스 변수와 클래스 변수가 동시에 있다면, 인스턴스 변수를 먼저 찾는다. 만약 인스턴스 변수가 없다면 클래스 변수가 있는지 찾는다.

 

 


 

2. 메서드

 

위 Car 클래스의 내부에 인스턴스 메서드, 클래스 메서드, 정적 메서드(static method)를 정의한다.

	# 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_calc(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
        return '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.'

 

 

@classmethod : 클래스 메서드

일반적인 인스턴스 메서드처럼 첫 번째 인자로 self를 받는 것이 아니라 클래스를 받는다.

—> 인스턴스 변수나 클래스 변수 모두 직접 접근하지말고 메서드를 만들어서 수정이나 조회가 가능하도록 하는 것이 안전하고 명시적이다. 위 get_price 메서드 처럼 self._price 변수에 접근 시 inst._price를 직접 호출하는 것이 아니라 inst.get_price의 메서드 형태로 변수에 접근한다(getter).

 

 

@staticmethod

아무런 파라미터를 받지 않으며 인스턴스의 상태를 변화시키지 않는 순수 함수의 용도로만 사용한다. 인스턴스 메서드와 클래스 메서드로 구현이 가능하기 때문에, 굳이 필요없다는 의견도 있다.

스태틱 메서드는 인스턴스로 호출해도 되고, 클래스로 호출해도 된다.

 

 


참조

 

1. 인프런 강의 - 우리를 위한 프로그래밍 : 파이썬 중급 (Inflearn Original)

https://www.inflearn.com/course/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%A4%91%EA%B8%89-%EC%9D%B8%ED%94%84%EB%9F%B0-%EC%98%A4%EB%A6%AC%EC%A7%80%EB%84%90/dashboard

728x90
반응형