본문 바로가기
TIL

[python] decorator 파이썬 데코레이터 이해하기

by _KHK 2022. 1. 22.

 

데코레이터는 함수에서 코드를 바꾸지 않고 추가하거나 수정하고 싶을 때 사용하는 문법이다.

처음 이해하기 조금 난해할 수 있지만 사용 이유, 단순하게 이해할 수 있는 순서 

그리고 현실적인 예제 등을 기록하려고 한다.

 

 


데코레이터를 사용하는 이유

 

기존에 만들어진 함수가 다른 곳에서 이미 많이 사용되고 있을 때 (= 함수 코드의 변경이 어려운 경우) 코드를 변경하지 않고, 필요한 내용을 추가하거나 수정하고 싶을 때 사용한다.

 

데코레이터가 유용하게 사용되는 코드

위 코드는 a와 b함수에 공통적으로 포함되어 사용되는 code1과 code3이 있다. code1과 code3이 포함된 함수를 별도로 선언하고 사용되면 좋겠다고 느껴질 것이다.  데코레이터는 중복 코드를 재활용하는 과정에 사용한다고 이해할 수 있다.

 

 

 

 


데코레이터 함수 사용법 이해

 

데코레이터의 사용법

데코레이터 사용법

아래 순서대로 이해할 수 있도록 최대한 쉽게 요약해보았다.

 

[step 1] @ 의미 이해

데코레이터가 필요한 a, b 함수 위에 @c가 되어있다.

@ + 함수명으로 데코레이터로 선언한 함수의 네이밍 c를 붙여주었다.

 

[step 2]  데코레이터 코드 이해

2-1 : 데코레이터 함수 c는 인자로 함수(func)을 받는다. => 위 코드에서 func는 데코레이터를 붙여준 함수 a와 b가 될것이다.

2-2 : 데코레이터 함수 안에 wrapper 라는 함수를 선언한다.

2-3 : wrapper 함수가 실질적인 작업 코드로 최종 결과를 return한다.

2-4 : 데코레이터 함수 c는 wrapper 함수를 return 한다.

 

[step 3] wrapper 함수 이해

wrapper 함수는 실질적으로 작업을 수행하는 함수이다.

 

3-1 : wrapper 함수는 기존 a, b 함수가 어떻게 선언되어있는지 모른다는 가정하에 모든 변수를 받을 수 있는 *args, **kwargs 를 인자로 선언한다.

3-2 : 이제부터는 작업 코드를 필요에 맞게 작성해주면된다.

궁극적인 목표였던 중복된 코드1과 코드3이 사용되어져야 하며, 데코레이터 함수의 인자로 받은 func가 사용되어야 한다.

3-3 : wrapper 함수는 리턴이 있을 수도 있고 없을 수도 있다. wrapper함수의 return은 작업 수행중 선택사항이다.

 

[step 4] 데코레이터 흐름 이해

step 3까지 코드를 이해 했다면 거의 다 이해했다고 생각할 수 있고, 최종적으로 흐름을 한번 더 이해하면 도움이 된다.

데코레이터 c함수는 결과적으로 c함수 안에서 선언된 wrapper함수를 다시 리턴한다.

a, b함수에서 사용된 코드들은 wrapper함수에서 원하는 위치에 삽입되어 사용 가능하다.

 

4-1 : 데코레이터 c 함수 선언

4-2 : a, b 함수에 데코레이터 추가

4-3 : 데코레이터 안에서 wrapper 함수 작성

4-4 : 데코레이터 최종 결과 리턴값

@c(a) ==> wrapper() 

@c(b) ==> wrapper() 

 

 


데코레이터의 실 사용 예제

 

위 코드를 개념처럼 이해하는 것보다 실제로 사용되는 예제를 공부하면서 이해에 더 도움이 된다.

 

학생들 평균을 계산하는 코드를 작성해봤다.

 

만약 위 get_avg 함수가 교내 교직원만 사용되어야만 하는 함수라서 교직원 비밀번호를 입력해야만 사용할 수 있다고 가정한다.

이때 교내에서만 사용하는 비밀번호를 확인하고 실행할 수 있는 데코레이터 함수를 선언할 수 있다.

비밀번호를 확인하는 데코레이터 함수

 

위에서 설명했듯이 데코레이터를 선언하고 사용하면 결과적으로는 wrapper함수가 실행되는 것이다.

input으로 비밀번호를 입력받고 비밀번호가 맞으면 데코레이터 함수로 전달한 func 즉, get_avg() 함수를 실행하고, 비밀번호가 맞지 않으면 "잘못된 비밀번호입니다."를 반환한다.

 

데코레이터를 사용한 get_avg함수

 

단순히 get_avg함수에 비밀번호를 확인하는 데코레이터 함수를 추가해 실행한 모습이다.

 

비밀번호 일치 경우 코드를 실행

 

비밀번호 불일치 "잘못된 비밀번호입니다" 리턴

 

실제로 웹에서 매번 로그인 체크를 확인하는 코드를 데코레이터를 사용하면 유연하게 코드를 작성할 수 있다. 

로그인이 되어야만 실행할 수 있는 코드를 작성하는 경우 하는 경우 로그인을 확인하는 데코레이터 함수만 작성해 두면 유용하게 사용될 수 있다.

 

실 사용 예제는 로그처리, 로그인 체크, 등등 여러가지가 있을 수 있다.

댓글