• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

데코레이팅 실행 오류 및 전달과정 문의

20.04.07 14:43 작성 조회수 177

1

import time

def time_checker(func):
def inner_function(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print('함수 {} 동작시간: {}'.format(func.__name__, end_time - start_time))
return result

return inner_function()


@time_checker # 위함수를 데코레이팅하여 함수를 확장하여 사용
def test1():
for i in range(5):
time.sleep(0.1)


@time_checker
def test2():
for i in range(3):
time.sleep(0.1)


test1()
test2()


질문1) 위코딩시 실행시 아래와 같은 에러메세지도 같이 출력됩니다. 

D:\Python36\python.exe D:/workpy/ch01/test.py

함수 test1 동작시간: 0.5036873817443848

Traceback (most recent call last):

  File "D:/workpy/ch01/test.py", line 26, in <module>

    test1()

TypeError: 'NoneType' object is not callable

함수 test2 동작시간: 0.302156925201416

Process finished with exit code 1

질문2) 

아래 코드는 0.5초 지연시키는 코드인데 @time_checker함수에 정확하게 어떻게 전달이되어서 어떤 논리로 실행되는건가요?

result = func(*args,**kwargs)로 전달되어 실행이 되는거라면 result  =  변수 선언이 반드시 필요한가요? 그리고 마지막에 return result를 해주는 이유도 궁금합니다. 

@time_checker  # 위함수를 데코레이팅하여 함수를 확장하여 사용
def test1():
for i in range(5):
time.sleep(0.1)

답변 1

답변을 작성해보세요.

1

1. time_checker 함수에서 리턴할때 inner_function을 () 호출하셔서 생기는 오류입니다. return inner_function 으로 괄호를 빼고 수정하시면 오류가 사라집니다.

2. result = function(*args, **kwargs) 가 데코레이터 된 함수(test1()) 를 호출하고 그 호출된 함수의 결과를 result 에 받아서 그 결과를 다시 호출된 지점으로 돌려주는 원리 입니다. 사실 이게 말이 더 어려운건데 현재 테스트하신 코드에서는 test1 함수가 리턴하는 값이 없으니 result 에도 결과가 없겠지만 데코레이터 함수는 결국 어떤 함수의 형태던 그것을 수용할 수 있어야 하기 때문에 어떠한 형태의 인자 (*args, **kwargs) 를 받고 그걸 실행 function() 하고 결과를 result = function() 담아서 돌려준다고 보시면 됩니다. return result 는 방금 얘기처럼 원래 호출된 위치로 결과값을 돌려줘야 하기 때문에 return 해야 합니다. 호출된 위치는 결국 쉽게 test1() 이렇게 호출된 지점을 말한다고 보시면 됩니다. test1()을 호출했지만 데코레이터는 test1을 바로 호출하는게 아니라  time_checker 함수가 먼저 수행되게 되기 때문에 그것을 가로채서 수행후 원래 함수인 test1 을 실행해야만 하기 때문입니다.

생각보다 말이 참 어렵게 느껴지는 부분입니다.