Data Engineer

python - 데코레이터와 데이터클래스

jssvs 2024. 6. 28. 00:58
반응형

 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 타입 인스턴스만 인자로 받기 때문에 에러가 여전히 발생할겁니다.

 

결과적으로 데이터클래스 데코터레이터를 이용하면 작성해야 할 코드를 생략할 수 있어요.  데이터클래스 데코레이터를 이용해서 특수 메서드들이 자동으로 추가된 겁니다.

 

필요하면 활용해보세요. :)

 

끝.

반응형