@ 는 데코레이터로 아래의 참고 사이트를 보고 공부.
@foo 와 @zoo 는 함수를 인자로 가지는데, 바로 아래에 있는 bar를 함수인자로 가지게 된다.
따라서 bar 함수의 선언문과 가까운 순서부터 실행이 된다.
그러므로 bar1=zoo(bar) 가 실행이 되고, bar=foo(bar1)이 실행이 된다고 생각하면 된다. (많이 헷갈림)
<출력되는 순서>
bar1=zoo(bar)
bar 함수 포인터가 zoo 로 넘어간다. 그리고 그 모든 정보를 담은 wrapper 함수 포인터가 return 된다.
그래서 bar1 에 zoo 의 wrapper 함수 포인터가 넘어간다. 그리고 이 wrapper 함수의 f 는 bar가 된다.
bar=foo(bar1)
bar1 은 zoo의 wrapper 함수 포인터이다. 이게 foo의 함수 포인터 인자로 넘어간다.
그리고 foo 의 wrapper 함수를 return 한다. 이 foo 의 wrapper 함수 포인터는 bar 로 넘어간다. 그리고 이 wrapper 함수의 f값은 bar1이 된다.
따라서 최종적으로 bar는 foo의 wrapper 함수의 포인터가 넘어오게 되면서, 이전의 모든 정보를 가지고 있다.
그래서 이제 bar(20,"heewok")을 실행시키면
1. bar 는 foo 의 wrapper 함수 포인터이므로 foo의 wrapper 함수를 실행한다.
2. print(msg) 이 부분이 출력이 된다.
3. 그리고 f 함수 포인터를 return 하는데 foo의 f는 zoo의 wrapper 함수 포인터 이므로 실행이된다.
4. zoo의 wrapper 함수 부분이 출력이되므로 시간값이 출력된다.
5. 그리고 zoo 의 wrapper 함수가 f를 실행시키면서 return 한다.
6. zoo 의 f는 진짜 bar 함수이므로 이제 선언된 bar 함수를 실행한다.
<코드와 결과>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | def foo(f): msg = f"hello {f.__name__}" def wrapper(*a,**k): print(msg) return f(*a,**k) return wrapper def zoo(f): import datetime t1 = datetime.datetime.now() def wrapper(*a,**k): print(datetime.datetime.now()) print(t1,end=' ') print('msec') return f(*a,**k) return wrapper @foo @zoo #bar1=zoo(bar) #bar=foo(bar1) def bar(name,age): print(f"{name} is {age} years old") bar(20,"heewok") bar(age=20,name="heewook") |
1 2 3 4 5 6 7 8 | hello wrapper 2018-06-26 16:08:39.722620 2018-06-26 16:08:39.722620 msec 20 is heewok years old hello wrapper 2018-06-26 16:08:39.722620 2018-06-26 16:08:39.722620 msec heewook is 20 years old | cs |
참고사이트
'잡다한 IT > 파이썬' 카테고리의 다른 글
파이썬 __str__ 와 __repr__ (0) | 2018.06.28 |
---|---|
파이썬 self (0) | 2018.06.28 |
shallow copy 와 deep copy (0) | 2018.06.27 |
클로져 (0) | 2018.06.26 |
list comprehension (0) | 2018.06.26 |