python - 데코레이터와 데이터클래스
1.데코레이터
많이들 아시겠지만 파이썬에는 데코레이터라는 기능이 있습니다. 보통 함수나 메소드에 적용하는 기능인데, 함수나 메서드의 기능을 확장하거나 변경하는 역할을 합니다.
예를 들어 제가 아래와 같이 어떤 처리 함수 my_func를 만들었습니다. 그런데 함수의 성능을 측정하기 위해 함수의 실행시간을 체크하고 싶어요.
함수를 수정할 수도 있겠지만, 저라면 runtime_check 라는 데코레이터로 만들어서 여러 함수에 적용해볼 수 있을 것 같습니다. 아래 코드 처럼 데코레이터를 써볼 수 있습니다.
import time
def runtime_check(func):
def func_wrapper():
start_time = time.time()
func() # 데코레이터를 적용한 함수가 호출되는 부분
end_time = time.time()
print(f"runtime : {(end_time - start_time):.4f}")
return func_wrapper # wrapper 함수 자체를 반환
@runtime_check
def my_func():
print("function call..")
time.sleep(2)
my_func()
이 처럼 데코레이터 내부에서의 동작은 기존 함수에 로직을 더해 새로운 함수를 만들고 반환하는 방식입니다.
2.데이터클래스
데이터클래스는 모듈 수준의 데코레이터라고 할 수 있어요.
예제 코드를 보면서 설명해보겠습니다.
# 데이터클래스 데코레이터를 쓰기 위한 import 선언 문이구요.
from dataclasses import dataclass, asdict
@dataclass # 데코레이터는 @ 예약어를 씁니다.
class Customer: # 고객 클래스를 선언하구요.
name: str # 이름, 나이, 이메일 정도의 클래스 멤버 변수를 만들구요
age: int
email: str
# 2개의 객체를 만들어보았습니다.
c1 = Customer("jss1",20,"jss@test.com")
c2 = Customer("jss1",20,"jss@test.com")
# 객체를 출력하고, 객체간의 비교를 해봤습니다.
# 그리고 마지막으로 클래스 정보를 json 오브젝트로 변환하기 위해 python dictionary 로 변환해보겠습니다.
print(c1) # Customer(name='jss1', age=20, email='jss@test.com')
print(c2) # Customer(name='jss1', age=20, email='jss@test.com')
print(c1==c2) # True
print(asdict(c1)) # {'name': 'jss1', 'age': 20, 'email': 'jss@test.com'}
네 특별한 게 없는 것 같죠..?
그럼 위 코드에서 @dataclass 를 빼고 실행해보시기 바랍니다.
그럼 아마도... 아래와 같은 에러가 발생할 거에요
TypeError: Customer() takes no arguments
그럼 에러를 처리하기 위해 직접 구현해보겠습니다.
class Customer:
name: str
age: int
email: str
# 객체 초기화를 위한 특별 메소드
def __init__(self,name,age,email):
self.name = name
self.age = age
self.email = email
# 객체를 문자열로 표현해주는 특별 메소드
def __str__(self) -> str:
return f"name : {self.name} age : {self.age} email : {self.email}"
# 객체 비교 특별 메소드
def __eq__(self, value: object) -> bool:
return True if self.age == self.age else False
위 코드는 객체를 출력하기 위해 __str__ , 객체를 비교하기 위한 __eq__ , 객체의 생성과 초기화를 위해 __init__ 을 구현해습니다.
** asdict()는 dataclass 타입 인스턴스만 인자로 받기 때문에 에러가 여전히 발생할겁니다.
결과적으로 데이터클래스 데코터레이터를 이용하면 작성해야 할 코드를 생략할 수 있어요. 데이터클래스 데코레이터를 이용해서 특수 메서드들이 자동으로 추가된 겁니다.
필요하면 활용해보세요. :)
끝.