getattr 은 어떤 클래스(혹은 인스턴스)의 attribute(필드나 메서드)를 가져오는 함수입니다.
예를 들면 아래와 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classDummyClass:def__init__(self):self.description="이 클래스는 간단한 사칙연산을 담당합니다."defadd(self,a:int,b:int):returna+bdefsub(self,a:int,b:int):returna-bdefmul(self,a:int,b:int):returna*bdefdiv(self,a:int,b:int):returna/b# 필드에 접근
dc=DummyClass()description=getattr(dc,"description")print(description)# 메서드에 접근
add_ex=getattr(dc,"add")print(add_ex(10,1))
1
2
3
# 출력
이 클래스는 간단한 사칙연산을 담당합니다.
11
응용
(1) 단일 로직으로 클래스의 함수를 동적으로 불러오기
getattr은 문자열로 클래스의 속성을 가져올 수 있습니다.
이 기능을 응용해서 짧은 코드로, 클래스의 함수를 동적으로 불러오는 코드를 작성해보겠습니다.
1
2
3
4
5
6
7
8
9
10
defdynamic_dummy_func(method:str,a:int,b:int):dc=DummyClass()func=getattr(dc,method)returnfunc(a,b)# 함수 외부에서 각 method별 계산 수행
print(dynamic_dummy_func("add",10,1))print(dynamic_dummy_func("sub",10,1))print(dynamic_dummy_func("mul",10,1))print(dynamic_dummy_func("div",10,1))
1
2
3
4
5
# 출력
11
9
10
10.0
(2) 변수에 넣지 않고 바로 함수로 사용할 수 있음
1
2
dc=DummyClass()print(getattr(dc,"add")(10,2))
1
2
# 출력
12
(3) 정적 타입 힌트를 통해 접근할 수 있는 속성을 제한하면 좋다.
1
2
3
4
5
6
7
8
9
10
Attrs=[attrforattrindir(DummyClass)ifnotattr.startswith("_")]deffunc(method,a,b):ifmethodinAttrs:# method에 대한 검증을 위함
dc=DummyClass()print(getattr(dc,method)(a,b))else:print(f"Invalid method: {method}")func("wrong method",1,2)
1
2
# 출력
Invalid method: wrong method
(4) 응용
requests에 응용할 수 있다.
requests는 HTTP 요청을 보내고 응답을 받아오는 라이브러리인데, 이 요청의 method는 get, post 등 여러 가지가 있다.
이를 아래와 같이 통일되게 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
# 기존의 requests 사용법
importrequestsresponse=requests.get(url)response=requests.post(url,json=body)# getattr을 이용하기
response=getattr(requests,"get")(url)response=getattr(requests,"post")(url,json=body)# --> 기존의 requests 에서는 HTTP 통신 방법(get, post...)이 바뀌면 사용하는 함수를 바꿔야 했음
# --> getattr을 이용하면 동일한 로직(함수)를 쓰면서, 함수에 사용되는 인자들만 바꿔주면 됨
Comments