본문 바로가기

잡다한 IT/파이썬

데코레이터

@ 는 데코레이터로 아래의 참고 사이트를 보고 공부.


@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")

cs


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




http://whatisthenext.tistory.com/113


참고사이트



반응형

'잡다한 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