ABOUT ME

IT와 컴퓨터 관련 팁, 파이썬 등과 아파트 정보, 일상적인 경험 등의 생활 정보를 정리해서 올리는 개인 블로그

  • 파이썬의 일급 객체 함수 개념을 이용한 클로저(closure) 연습
    코딩 연습/코딩배우기 2020. 11. 10. 17:02
    반응형

     

    파이썬 클로저(closure)

    ■ 클로저는 스코프에 묶인 변수를 바인딩 하기 위한 기술로, 파이썬에서 __closure__는 cell(셀)로 이루어진 튜플이며, cell 객체는 __closure__의 free variables(변수)를 저장하기 위해 사용되고, 각 cell에는 저장된 값을 확인할 수 있는 cell_contents라는 변수(속성)가 있다.

    def closure_ex1():
        x = 1
        
        def inner():
            y = 2
            return x + y
        
        return inner
        
    
    r1 = closure_ex1()
    print(r1, type(r1))  ## 리턴값은 inner 함수의 참조값
    # <function closure_ex1.<locals>.inner at 0x0000023B36A21BF8> <class 'function'>
    
    print(hasattr(r1, '__closure__'))  ## r1에 속성 __closure__ 있는지
    # True
    
    print(r1.__closure__)  ## int x의 위치는
    # (<cell at 0x0000023B369D5FD8: int object at 0x00007FF9E5F79340>,)
    
    print(type(r1.__closure__[0]))
    # <class 'cell'>
    
    for attr in dir(r1.__closure__[0]):  ## 튜플의 res.__closure__[0] 속성들은
        print(attr)
    
    #__class__
    #__delattr__
    #__dir__
    #__doc__
    #__eq__
    #__format__
    #__ge__
    #__getattribute__
    #__gt__
    #__hash__
    #__init__
    #__init_subclass__
    #__le__
    #__lt__
    #__ne__
    #__new__
    #__reduce__
    #__reduce_ex__
    #__repr__
    #__setattr__
    #__sizeof__
    #__str__
    #__subclasshook__
    #cell_contents
    
    
    ## 객체의 변수(속성)인 cell_contents
    print(r1.__closure__[0].cell_contents)  ## int x의 값은
    # 1
    
    print(r1())  ## 리턴된 함수의 실행
    # 3
    
    def closure_ex2(x, y):
        x = x
        y = y
        
        def inner():
            return x ** y
        
        return inner
    
    r2 = closure_ex2(2, 32)
    print(r2)
    # <function closure_ex2.<locals>.inner at 0x0000023B36A9C8C8>
    
    print(r2.__closure__)
    # (<cell at 0x0000023B36ACDD68: int object at 0x00007FF9E5F79360>, <cell at 0x0000023B36ACDD98: int object at 0x00007FF9E5F79720>)
    
    for c in r2.__closure__:
        print(c.cell_contents)
    
    #2
    #32
       
    print(r2())
    # 4294967296
    

    good4me.co.kr

     

    def closure_ex3(x, y):
        x = x
        y = y
        
        def inner(x, y):
            return x ** y
        
        return inner
    
    
    r3 = closure_ex3(2, 32)
    print(r3)
    # <function closure_ex2.<locals>.inner at 0x0000023B36ABFAE8>
    
    print(r3.__closure__)
    # None
    
    #print(r3())
    # TypeError: inner() missing 2 required positional arguments: 'x' and 'y'
    
    ## closure_ex3 함수의 x, y 변수와 내부 inner 함수의 x, y 변수는 다름
    print(r3(2, 32))
    # 4294967296
    
    
    
    
    ## closure_ex3 내 inner 함수를 람다 함수로 변경
    def closure_ex4(x, y):
        x = x
        y = y
        
        return lambda x, y: x ** y
    
        
    r4 = closure_ex4(2, 32)
    print(r4)
    # <function closure_ex4.<locals>.<lambda> at 0x0000023B36AD1048>
    
    print(r4.__closure__)  
    # None
    
    print(r4(2, 32))
    # 4294967296
    

     

    반응형
Designed by goodthings4me.