Language/Python

TIL-파이썬-장식자(클로져),스코프(범위)[Python-Decorator(Closure), Scope]

청렴결백한 만능 재주꾼 2020. 4. 24. 18:31
반응형

어제의 기록에 설명을 다 해놔서 고민하고 막히고 고민했던 부분만 업데이트를 해야겠다.

 

repl.it으로 진도 나가는 중 겪은 문제 Decorator 실습 문제

일단 단순 데코레이터의 기본구조(내가 배운,내가 느낀)

1.def decorator(func):      -->>여기서 func은 함수를 받는다 이거고

2.   def wrapper(x):     -->> 여기서 와퍼는 그냥 와퍼고 단어그대로 감싼다고 보면됩니다.

3.         print("출력한다 나는 1번이다.")

4.         func(x)

5.         print("출력한다 나는 2번이다.")

6.         return x             --->>와퍼 사이에는 무슨 짓을 해도 된다.

7.    return wrapper        --->> 여기서 밑에 함수를 리턴해서 와퍼를 감싸준다.

          

8.@decorator

9.def name(x):

10.   print("Hello, I am "+ str(x))

 

name("John")    


자 name("John")을 호출해보면 결과가 다음과 같이 나온다.


출력한다 나는 1번이다.     ----Warpper함수의 프린트가 발동

Hello, I am John             ----4번 line의 func(x)가 발동되어 밑에 name(x)함수가 가져와짐.

출력한다 나는 2번이다.    ----Warpper함수의 프린트가 발동

Output : 'John'               ----Output이 나온 이유는 6번 line에 return 때문이다.


일단 결과에 대해서는 설명을 하였고 파이썬의 흐름을 말하자면 

name('John')이 호출 되었을 때에

9번줄이 호출 되는데 선행되어야할 데코레이터가 붙어있기 때문에 8번으로 간다.

데코레이터를 호출하기 위해선 1번으로 가게 되고 7번이 리턴된다.

7번이 리턴되려면 2번으로 가야하고 와퍼함수가 쫙 실행된다.

 

솔직히 여기까지는 괜찮았다. 

parameter와 argument의 이해관계가 굉장히 어려웠다.

 

사실 데코레이터를 쓰는 방법이 여러 개가 있는데 그 중 하나가 @로 묶는거고 다른 방법도 많다.


문제에서는 데코레이터에 인자가 붙어야 한다고 하여서 멘붕이 왔다. 다들 힘들었을 거라고 멘탈을 붙잡지만...

혼자서 끙끙대면서 앓다가 푼다 vs 고민 좀 하다가 멘토나 주변 사람에게 물어본다.

일단 이해가 안되어서 물어봤자 그냥 단순 정답 갈증 해소일 뿐 진정 내 것이 아닌걸 다 알기에.

다행히 이해하고 정리한다.  

 

클로져에서 생각한 것 처럼 
첫 번째 데코레이터 인자는 함수자체로 받는다. ex) 인자이름 = 'func', 여기에 적용될 것: name

두번째 와퍼의 인자는 name함수가 받을 인자를 뜻한다. 그러니까 name에서 벌어질 일을 warper에서 정해줘도 된다.

그리고 가공을 해놔도 되고 name에서 일어날일들과 합쳐져서 말해도 되고 응용은 가능하다.

 


def name_decorator(name):
    def real_decorator(func):
        def decorated():
            return func() + name
        return decorated
    return real_decorator

@name_decorator("정우성")
def greeting():
    return "Hello, "


 

정답은 이렇게 내었다. 통과되었다. 정말 한 4~5시간 투자했는데 어제까지 합치면... 그이상인데 이게 엄청 대단한 일을 한게 아니고 100만단계에서 1계단 올랐다는 것이 정말 갑갑하다~ㅋㅋ 

 

그리고 간단한 스코프// 복잡하기도한 스코프

Scope

Scope은 범위라는 뜻입니다.

프로그래밍 언어에서 scope은 어떠한 객체 (변수, 함수 등)가 유효한 범위를 이야기 합니다.

범위를 벗어나면 해당 객체는 사용될 수 없습니다.

 

Python에서 scope은 항상 객체가 선언된 지점에서 위로는 상위 객체 까지, 아래로는 모든 하위 객체들과 그 안에까지가 범위 입니다. 어떤 뜻인지 차근 차근 보겠습니다.

 

범위에는 크게 다음 4가지가 있습니다.

 

  • Local Scope

  • Enclosed Scope

  • Global Scope

  • Built-in Scope

Shadowing

파이썬은 변수나 함수의 정의를 찾을때 다음 순서의 scope들 안에서 찾습니다.

 

Local => Enclosing => Global => Built-in

 

즉 가장 좁은 유효범위 부터 시작 해서 넓은 범위로 나아가며 사용되는 변수나 함수의 정의를 찾습니다.

그러므로 만일 동일한 이름의 변수들이 서로 다른 scope에서 선언이 되면 더 좁은 범위에 있는 변수(혹은 함수)가 더 넓은 범위에 있는 변수를 가리는 (shadowing)효과가 나타납니다

 


이런 효과도 있다더라. 쉬운 과제는 금방 끝이 났고, 오늘은 여기까지 할 예정이다. ㅎㅎㅎ

반응형