2014-07-16 2 views
1

나는이 코드 조각을 가지고 있고, 그것이 실행의에 대해 내가 혼란 스러워요 : 그것은 단지 함수의 두 번째 호출에 합계 x+y를 만드는 이유파이썬 실행 중첩 된 기능

def makeInc(x): 
    def inc(y): 
     return y + x 
    return inc 

inc5 = makeInc(5) 
# print inc5 ---> <function inc at 0xb721bdbc> 
inc5(12) 
# print inc5(12) gives 17 

그래서, 궁금 inc5(). 파이썬의 클로저가 실제로 무엇을 의미하는지 알지만 여전히 혼란 스럽습니다.

나는이 웹 페이지에 코드의 조각을 발견했다 : http://ynniv.com/blog/2007/08/closures-in-python.html

+0

코드를 실행하면 'inc5 (12)'의 결과가 17이됩니다. –

+0

죄송합니다. 17, 올바르게 수정합니다 – redenigma

+0

코드에서 한 번만 inc5를 호출합니다. "첫 번째 호출"은 완전히 별도의 함수 인'makeInc'입니다. –

답변

2

다른 대답을 잘 설명하지만, 여기에 코드에서이 객체로 함수의 개념 이해

def makeInc(x): # define a function makeInc that takes a variable x 

    # when makeInc is executed, define a function "inc" that takes a variable y 
    def inc(y): 
     # when inc is executed, return the sum (where x is closed in the outer function) 
     # note this is not executed when makeInc is called 
     return y + x 

    # don't call inc yet, just return a reference to the function itself - note there 
    # are no parenthesis after inc 
    return inc 

inc5 = makeInc(5) # now execute makeInc which returns a reference to the inc function 
        # with the variable x captured by the closure 

inc5(12) # now call the result of the above which is the only place that we call inc 
      # note the parenthesis to designate the function call 

# print inc5(12) gives 17 

중앙 무슨 라인 고장에 의하여 선이다. 파이썬에서이 작업을 수행 할 수 있습니다

makeInc가 호출
>>> def test(x): 
...  return x + 6 
... 
>>> test(1) # call test with the argument x = 1 
7 
>>> a = test # assign the function "test" to a new variable "a" - this is not calling test 
>>> a 
<function test at 0x101cfbb90> # printing a shows the original function name "test" 
>>> a(1) # now call that function again with the same value for x = 1 
7 

, 그것은 (Y라는 주장을 복용) 다른 기능의 서명이있는 내 inc에 대한 참조를 반환합니다. 둘 다 단일 인수를 취한다는 사실은 적합하지 않습니다.

+0

자리 표시. 여기도 좋은 자료입니다. http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/ –

+0

위대한 두 번째 예가 이제 더 명확 해졌습니다. 첫 번째 호출에서 우리는 함수 inc()를 부모 함수 makeInc()에 할당합니다. 두 번째 호출에서 우리는 inc() 함수를 실제로 호출합니다.이 마지막 함수가 이전 x 변수를 인식하고 있기 때문에 합계는 훌륭하게 진행됩니다. 이제 알겠습니다 – redenigma

3

여기에 무슨 일이 일어나고 있는지에 대한 의견입니다.

makeInc은 다른 함수를 반환하는 함수입니다. 클로저를 사용하면 반환 된 함수는 약 x이 생성되고 반환 된 순간 true로 설정되어 있음을 알게됩니다.

inc2 = makeInc(5) 호출하는 제 5 세트 xmakeInc 내부하게하고 기능 y를 생성한다. 이 inc 함수는 x이 5라는 것을 알고 있으며, 그것이 살아있는 한 기억할 것입니다. 이것은 closure의 개념입니다. (출생시 환경에 필요한 모든 변수를 배낭에 넣으십시오).

inc5(12)을 호출하면 inc(12)이 실행됩니다. 이 호출은 inc로는 inc5 5가 기억 x의 값으로 인수 y 인 12을 추가, 그래서 합이 17

N.B : 클로저는 자바 스크립트 같은 언어에서 naturaly 사용하게 내부합니다. 파이썬에서 클로저는 을 사용할 수 있지만 너무 자주 사용하지는 않으며 일부 개발자는 악의적으로 생각하고 있습니다. 질문에 이 매우 명확하게 표시되어 있습니다. 코드에서 어떤 일이 일어나고 있는지 알기는 쉽지 않습니다.이 코드는 에 대한 것입니다. 카운트 "파이썬의 선에서. 또한 범위와 관련된 몇 가지 놀라움과 변수 표시 여부를 확인할 수 있습니다. 위의 코드에서 정확히 무슨 일이 발생하지 않았습니까? 걱정하지 마세요. Python은 많은 다른 멋진 구조를 제공합니다. 더 자주 사용하는 (목록 이해가 한 예입니다).

+0

귀하의 의견에 따르면, 나는 함수의 첫 번째 호출에서 makeInc() 우리는 그냥 inc() 함수를 만들고이 마지막 변수 x의 존재에 대해 알고 이해합니다. 두 번째 호출 inc5 (12)에서는 두 번째 함수 인 inc()를 호출합니다. 이 마지막 매개 변수가 어떻게 매개 변수를 취해 y로 생각하면 – redenigma

+0

@redenigma'inc5'는'inc '와 거의 동일하기 때문에 첫 번째 인자'y'를 갖는 서명에 대해 알고 있습니다. 'inc'와'inc5'의 유일한 차이점은'inc5'는 리턴 된 시간 ('x' 값에 영향을 미치지 만,'y'는 단지 인자 일뿐입니다)에 대한 환경을 ("배낭"에서) 기억합니다 나중에 'inc5'에 전화 할 때 설정하십시오.) –

+0

아이디어를 얻었습니다. 정말 감사합니다. – redenigma