(Python) instance method, class method, static method
instance method
가장 흔하게 쓰이는 메서드로 생성된 인스턴스 변수에 접근할 수 있도록 첫번째 인자에 항상 객체 자신을 의미하는 self파라미터를 갖는다.
접근방법
클래스 내부에서는 self.메서드명
으로 접근이 가능하고 클래스 밖에서는 객체.메서드명
으로 접근이 가능하다
class method
클래스 메서드는 인스턴스 없이 호출이 가능하다. 즉 클래스 변수에 대한 메서드라고 생각하면 된다. (클래스변수의 crud가 필요한 경우 사용) 첫번째 인자에 항상 클래스를 의미하는 cls 파라미터를 갖는다. cls를 사용하면 클래스 메서드 내부에서 현재 클래스의 인스턴스를 만들수도 있다.
접근방법
@classmethod 라는 데코레이터를 붙여 해당 메서드가 클래스 메서드임을 표시한다
호출방법으로는 클래스명.클래스메서드명
or 객체명.클래스 메서드명
static method
객체에 영향을 받지 않는 독립적인 메서드이지만 로직상 클래스 내부에 포함되는 메서드이다. self, cls와 같은 파라미터를 가지고 있지 않다. 그렇기 때문에 인스턴스 변수에 접근이 불가능하다. 하지만 클래스 변수에는 클래스명,클래스속성명으로 접근이 가능하다.
정적 메서드는 메서드의 실행이 인스턴스 상태에 영향을 끼치지 않을때 사용한다.
접근방법
@staticmethod 라는 데코레이터를 붙여 해당 메서드가 정적 메서드임을 표시한다.
호출방법으로는 클래스명.정적메서드명
or 객체명.정적메서드명
아래의 코드는 지금까지 설명한 내용들을 활용한 실습 코드이다. 방금 본 내용들을 적용시키며 천천히 읽어보자.
### 3가지 메서드를 활용한 실습 코드
class Car():
# class 설명서 __doc__ 로 볼 수 있음
"""
Car class
Author: kim
Date:2021.07.05
Description: class, static, instance method
"""
# 클래스 변수(모든 인스턴스가 공유)
price_per_raise = 1.0
# 이곳 안에서 인스턴스 변수 생성됨
def __init__(self, company, details):
self._company = company
self.car_count = 10
self._details = details
# str과 repr
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 get_price(self):
return 'Before Car Price -> company: {}, price: {}'.format(self._company, self._details.get('price'))
# 인스턴스 메서드
def get_price_culc(self):
return 'After Car Price -> company: {}, price: {}'.format(self._company, self._details.get('price') * Car.price_per_raise)
# 클래스 메서드
@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.')
# 스태틱 메서드
# utils형으로 유연하게 사용될때 사용
@staticmethod
def is_bmw(inst):
if inst._company == 'Bmw':
return 'ok! this car is {}'.format(inst._company)
return 'Sorry this car is not Bmw'
car1 = Car('Ferrari',{'color':'Silver','horsepower':300,'price':6000})
car2 = Car('Bmw',{'color':'Black','horsepower':270,'price':5000})
# 전체 정보
car1.detail_info()
car2.detail_info()
print()
print()
# 가격 정보(직접 접근)
print(car1._details.get('price')) # 변수값이 변경 될 수 있기 때문에 직접 자기 인스턴스 변수에 접근하는 것은 좋지 못한 방법임
print(car2._details['price']) # 마찬가지로 값이 변경 될 위험이 있기때문에 좋지 못한방법
# 보통은 메서드를 만들어서 필요로하는 정보만 반환받게 사용함
print()
print()
# 가격 정보 (인상전)
print(car1.get_price())
print(car2.get_price())
print()
# 가격 인상(클래스 메서드 미사용) -> 직접접근해서 변경하는 것 좋지 못하다. 메서드 만들자
# Car.price_per_raise = 1.4 # 40% 상승
print(car1.get_price_culc())
print(car2.get_price_culc())
print()
print()
Car.raise_price(1)
print()
# 가격인상(클래스 메서드 사용)
Car.raise_price(1.6)
print(car1.get_price_culc())
print(car2.get_price_culc())
print()
print()
# 인스턴스로 호출(스테이틱)
# staticmethod의 매개변수는 비워있다, 유연하고 메서드를 정의할때 좀 공통적으로 만드는데 유연하게 만들고 싶을때
# 자동차가 만개있을때 해당 자동차가 bmw에서 나온 자동차인지 확인하는 메서드
print(car1.is_bmw(car1))
print(car1.is_bmw(car2))
print()
print()
# 클래스로 호출(스테이틱)
# 스택틱 메서드는 클래스로도 호출이 가능하다, 공통적으로 클래스로 호출해도 된다
#클래스와 관련이 있는 기능을 조작하는데 매개변수로 Self나 cls등을 받지 않고도 동작이 가능할때 사용한다
print(Car.is_bmw(car2))
print(Car.is_bmw(car1))
코드 결과값
current ID : 140576165418264
car detail info : Ferrari 6000
current ID : 140576165474712
car detail info : Bmw 5000
6000
5000
Before Car Price -> company: Ferrari, price: 6000
Before Car Price -> company: Bmw, price: 5000
After Car Price -> company: Ferrari, price: 6000.0
After Car Price -> company: Bmw, price: 5000.0
please enter 1 or more
succeed! price increased.
After Car Price -> company: Ferrari, price: 9600.0
After Car Price -> company: Bmw, price: 8000.0
Sorry this car is not Bmw
ok! this car is Bmw
ok! this car is Bmw
Sorry this car is not Bmw