이번에 나눌 이야기는 파이썬 클래스에서 동적으로 메서드를 생성하는 방법에 대한 이야기입니다. dataclass 데코레이터의 동작 원리를 살펴보다가 알게된 내용을 정리해 봅니다.
EXEC 함수
먼저 exec 함수에 대해 알아봅니다.
이 함수는 텍스트로 작성된 코드를 실행하기 위한 용도로 사용됩니다. 즉, 파이썬 코드 문자열을 동적으로 실행하는 기능을 제공합니다.
exec('print("Hello World")')
이 코드를 실행하면 마치 파이썬 코드로 print("Hello World")를 실행한 것과 동일한 결과를 얻습니다. 여기까지는 많이들 보셨을 텐데요, exec 함수의 서명(signature)는 다음과 같습니다.
exec(object[, globals[, locals]])
두번째 인자와 세번째 인자는 스코프의 네임스페이스입니다. 따라서 특정 인수값을 전달하지 않으면 현재의 전역/지역 네임스페이스를 기반으로 실행됩니다.
exec(object) # 현재 스코프에서 코드 실행
exec(object, globals) # 주어진 전역 네임스페이스에서 실행
exec(object, globals, locals) # 전역과 지역 네임스페이스를 분리하여 실행
SETATTR 함수
setattr 함수는 객체의 속성을 동적으로 추가하거나 변경하는 함수입니다. 즉, 클래스/객체에 속성을 추가하거나 기존 속성을 수정할 수 있습니다. 이 함수의 서명은 다음과 같습니다.
setattr(object, name, value)
# object: 속성을 추가하거나 수정할 대상 객체
# name: 속성의 이름(문자열)
# value: 설정할 속성 값
예를 들어 빈 Person이라는 클래스를 만들고, 여기에 name이라는 속성을 동적으로 추가해 봅시다.
class Person:
pass # 빈 클래스 정의
p = Person()
# 동적으로 'name' 속성 추가
setattr(p, 'name', 'neozest')
print(p.name) # neozest
클래스에 메서드 동적으로 추가하기
파이썬에서 함수는 1급 시민입니다. 즉, 함수 자체를 인수로 주고 받을 수도 있습니다.
이번에는 Animal 클래스를 만들고, 여기에 speak 메서드를 동적으로 추가해 보겠습니다. 먼저 클래스 코드!
class Animal:
def __init__(self, name):
self.name = name
a = Animal("Dog")
a.speak() # AttributeError 발생!
AttributeError 예외가 발생했습니다. 당연한 결과죠. Animal 클래스에 speak 메서드가 정의되어 있지 않습니다.
이번엔 동적으로 메서드를 추가해 보겠습니다. 본질적으로 어떤 함수 정의 객체를 클래스에 추가하는 작업입니다. 이를 보다 추상화해서 특정 클래스에 특정 코드를 메서드로 추가하는 함수를 만들어 봅니다.
def add_method(cls, method_name, method_body):
code = f"def {method_name}(self): {method_body}"
exec(code, globals(), locals())
setattr(cls, method_name, locals()[method_name])
code는 함수를 선언하기 위해 만든 문자열입니다. 이 함수 정의 코드 문자열을 exec 함수를 사용하여 전역/지역 네임스페이스에서 실행합니다. 그렇게 만들어진 속성(메서드)를 setattr함수를 사용하여 특정 클래스의 신규 속성으로 등록합니다.
이제 Animal 클래스에 새로운 메서드를 추가한 후 speak 메서드를 호출해 봅니다.
add_method(Animal, "speak", 'print(f"{self.name} makes a sound")')
a = Animal("Dog")
a.speak() # Dog makes a sound
이제 문제없이 speak 메서드를 호출할 수 있습니다.
심지어 람다함수로도 메서드를 동적으로 추가할 수 있습니다.
setattr(Animal, "shout", lambda self: "Roar!")
print(a.shout()) # Roar!
마무리 - dataclass 데코레이터
dataclass 데코레이터는 클래스 정의를 자동화하는 기능을 제공하여 __init__, __repr__, __eq__와 같은 던더 메서드를 직접 작성하지 않아도 자동으로 생성해 줍니다. dataclass 데코레이터는 클래스의 __annotations__ 던더 속성을 이용하여 사용자 정의 클래스를 수정합니다. 이 속성은 클래스에 대한 메타정보,즉 변수, 속성, 함수 인자, 반환값 등에 대한 타입 힌트를 담고 있습니다. 이 속성을 이용하여 필요한 메서드를 동적으로 클래스에 추가할 수 있습니다.
알아두면 좋을법한 관련 정보
데코레이터, 네임스페이스에 대한 보다 자세한 이야기는 제가 번역하고 인사이트 출판사에서 펴낸 <Python How-To: 파이썬다운 코드를 개발하는 63가지 실용기법>의 다음 부분에 설명되어 있습니다.
- dataclass 데코레이터:Python How-to의 9.2절에 자세히 설명되어 있습니다.
- LEGB 네임스페이스 규칙: Python How-to의 10.3절에 자세히 설명되어 있습니다.
- 데코레이터: Python How-To의 7.3절에 자세히 설명되어 있습니다.
책을 구매하시면 출판사에서 더 좋은 파이썬 책을 만드는데 도움이 되지 않을까요. :)
알라딘: https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=369848931
교보: https://product.kyobobook.co.kr/detail/S000217294649
YES24: https://www.yes24.com/product/goods/151253343
파이썬다운 코드를 개발하는 63가지 실용 기법 | 프로그래밍 인사이트 Programming Insight | 용 추이
63가지 핵심 파이썬 기술을 익힐 수 있는 간단하지만 강력한 방법을 제시한다. 예를 들어, ‘시퀀스에서 항목을 찾으려면 어떻게 해야 할까?’와 같은 질문에서 출발하여 매우 명확한 기본 해결
www.aladin.co.kr
'2. 개발 > 2.2 Python' 카테고리의 다른 글
새로운 파이썬 패키지 관리 도구, uv (0) | 2025.08.23 |
---|---|
이미지 파일을 PDF 파일로 묶기 (0) | 2022.10.20 |
삽질기:맥에서 파이썬 모듈 설치시 특정 모듈 제외하기 (0) | 2016.04.26 |
[파이썬] 터미널에서 컬러 텍스트 출력하기 (0) | 2014.05.28 |
VS를 파이썬 IDE로 사용하기. (0) | 2014.04.18 |