문제

def maker(n):
    def action(x):
        return x ** n
    return action

f = maker(2)
print(f)
print(f(3))
print(f(4))

g = maker(3)
print(g(3))

print(f(3)) # still remembers 2

중첩 된 기능이 첫 번째 값을 기억하는 이유는 무엇입니까? 2 ~ 일지라도 maker() 당시에 돌아와서 종료되었습니다 action() 호출 되나요?

도움이 되었습니까?

해결책

부모 함수에서 발생하는 모든 변수가 어린이 함수 내부의 실제 값으로 대체되는 것으로 볼 수 있습니다. 이런 식으로, 자식 기능을 올바르게 실행하기 위해 부모 함수의 범위를 추적 할 필요가 없습니다.

"동적으로 함수 생성"으로 본다.

def maker(n):
  def action(x):
    return x ** n
  return action

f = maker(2)
--> def action(x):
-->   return x ** 2

이것은 파이썬의 기본 동작이며 여러 할당과 동일합니다.

a = 1
b = 2
a, b = b, a

파이썬은 이것을 읽습니다

a, b = 2, 1

기본적으로 값을 삽입하기 전에 값을 삽입합니다.

다른 팁

당신은 기본적으로 a 폐쇄.

컴퓨터 과학에서 폐쇄는 어휘 환경에 묶인 무료 변수를 가진 일류 기능입니다. 이러한 함수는 자유 변수를 통해 "닫힙니다"라고합니다.

관련 독서 : 폐쇄 : 왜 그렇게 유용합니까?

폐쇄는 단순히 로컬 상태에 대한 기능에 액세스 할 수있는보다 편리한 방법입니다.

에서 http://docs.python.org/reference/compound_stmts.html:

프로그래머의 메모 : 기능은 일류 개체입니다. 함수 정의 내부에서 실행되는 'def'양식은 반환 또는 전달 될 수있는 로컬 함수를 정의합니다. 중첩 된 함수에 사용되는 자유 변수는 DEF를 포함하는 함수의 로컬 변수에 액세스 할 수 있습니다. 자세한 내용은 섹션 이름 지정 및 바인딩을 참조하십시오.

두 가지 기능을 정의하고 있습니다. 전화 할 때

f = maker(2)

숫자의 두 배를 반환하는 함수를 정의하고 있습니다.

f(2) --> 4
f(3) --> 6

그런 다음 다른 다른 기능을 정의합니다

g = maker(3)

그 숫자의 세 배로 반환됩니다

g(3) ---> 9

그러나 그것들은 두 가지 다른 기능이며, 동일한 기능이 아닙니다. 각 기능은 독립적 인 것입니다. 함수 내부의 범위에서도 '메이커'가 동일하다고 불려면 호출 할 때마다 같은 기능이 아닙니다. maker() 다른 기능을 정의하고 있습니다. 그것은 로컬 변수와 같습니다. 함수를 호출 할 때마다 동일한 이름을 가져 오지만 다른 값을 포함 할 수 있습니다. 이 경우 변수 '액션'에는 함수가 포함됩니다 (다를 수 있음)

그것이 "라고 불리는 것"폐쇄". 단순히, 기능을 다음과 같이 처리하는 모든 프로그래밍 언어는 아니더라도. 일류 대상, 함수 객체 내에서 사용되는 모든 변수는 함수가 여전히 살아있는 한 밀폐됩니다 (예 : 기억). 당신이 그것을 사용하는 방법을 알고 있다면 그것은 강력한 개념입니다.

당신의 예에서, 중첩 action 함수는 변수를 사용합니다 n 따라서 해당 변수를 중심으로 클로저를 형성하고 이후 기능 호출에 대해 기억합니다.

내부 기능을 작성하는 세 가지 일반적인 이유를 살펴 보겠습니다.

1. 폐쇄 및 공장 기능

변수가 범위를 벗어나거나 함수 자체가 현재 네임 스페이스에서 제거 된 경우에도 동봉 스코프의 값이 기억됩니다.

def print_msg(msg):
    """This is the outer enclosing function"""

    def printer():
        """This is the nested function"""
        print(msg)

    return printer  # this got changed

이제이 기능을 호출해 보겠습니다.

>>> another = print_msg("Hello")
>>> another()
Hello

그것은 드문 일입니다. 그만큼 print_msg() 함수는 문자열로 호출되었습니다 "Hello" 그리고 반환 된 함수는 이름에 묶여있었습니다 another. 전화시 another(), 우리가 이미 실행을 마쳤음에도 불구하고 메시지는 여전히 기억되었습니다. print_msg() 기능. 이 기술은 일부 데이터 ("Hello") 코드에 첨부 된 것을 Python의 Closure라고합니다.

클로저를 언제 사용해야합니까?

그렇다면 폐쇄는 무엇에 좋은가? 클로저는 글로벌 값의 사용을 피하고 일부 형태의 데이터 숨기기를 제공 할 수 있습니다. 또한 문제에 대한 객체 지향 솔루션을 제공 할 수 있습니다. 클래스에서 구현할 방법이 거의 없으면 클로저는 대체적이고 더 우아한 솔루션을 제공 할 수 있습니다. 참조

2. 캡슐화 :

캡슐화의 일반적인 개념은 외부 세계에서 내부 세계를 숨기고 보호하는 것입니다. 여기서 내부 기능은 외부 기능 내부에서만 액세스 할 수 있으며 함수 외부에서 발생하는 모든 일로부터 보호됩니다.

3. 건조하게 유지하십시오

아마도 여러 곳에서 동일한 코드 덩어리를 수행하는 거대한 기능이있을 수 있습니다. 예를 들어, 파일을 처리하는 함수를 작성할 수 있으며 열린 파일 개체 또는 파일 이름을 수락하려고합니다.

def process(file_name):
    def do_stuff(file_process):
        for line in file_process:
            print(line)
    if isinstance(file_name, str):
        with open(file_name, 'r') as f:
            do_stuff(f)
    else:
        do_stuff(file_name)

자세한 내용은 참조 할 수 있습니다 이것 블로그.

함수를 만들 때 n ~였다 2, 당신의 기능은 다음과 같습니다.

def action(x):
    return x ** 2

F (3)을 호출 할 때 x 설정되었습니다 3, 당신의 기능이 반환됩니다 3 ** 2

사람들은 폐쇄에 대해 올바르게 대답했습니다.

이를 극복하는 한 가지 쉬운 방법은 Freevar (N)를 "Action"기능 내부의 변수로 만드는 것입니다.

이를 수행하는 가장 쉬운 방법은 "n"을 창조 순간에 기본값 값의 매개 변수로 설정하는 것입니다. 함수의 기본 매개 변수가 함수 자체의 속성 인 튜플에 저장되기 때문에 "n"에 대한이 값은 고정되어 있습니다 (이 경우 action.func_defaults).

def maker(n):
    def action(x, k=n):
        return x ** k
    return action

용법:

f = maker(2) # f is action(x, k=2)
f(3)   # returns 3^2 = 9
f(3,3) # returns 3^3 = 27

한 가지 사용은 매개 변수를 유지하는 함수를 반환하는 것입니다.

def outer_closure(a):
    #  parm = a               <- saving a here isn't needed
    def inner_closure():
        #return parm
        return a              # <- a is remembered 
    return inner_closure

# set parm to 5 and return address of inner_closure function
x5 = outer_closure(5)
x5()
>5

x6 = outer_closure(6)
x6()
>6

# x5 inner closure function instance of parm persists 
x5()
>5

DEF 키워드로 함수를 만들 때 정확히 다음을 수행합니다. 새 기능 객체를 작성하여 변수에 할당합니다. 당신이 제공 한 코드에서 당신에게 새로운 함수 객체를 action이라는 로컬 변수에 할당하고 있습니다.

두 번째로 부르면 두 번째 기능 객체를 생성합니다. 따라서 F는 첫 번째 함수 객체 (square-the-value)를 가리키고 G는 두 번째 함수 객체 (Cube-the-value)를 가리 킵니다. Python이 "F (3)"을 볼 때 "가리키는 기능 객체를 변수 f로 실행하고 값 3을 전달한다"는 의미로 사용됩니다. F와 G 및 다른 기능 객체는 다른 값을 반환합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top