>  기사  >  백엔드 개발  >  Python의 클로저에 대해 간략하게 설명

Python의 클로저에 대해 간략하게 설명

WBOY
WBOY원래의
2016-12-05 13:27:181102검색

Python의 클로저

요 며칠 전에 누군가가 메시지를 남겼는데, 闭包re.sub 중 어느 하나의 용도가 명확하지 않습니다. Script Home을 검색해 보니 클로저와 관련된 내용을 작성한 적이 없어서 Python의 내용을 요약하고 개선하기로 결정했습니다.

1. 폐쇄의 개념

우선 클로저란 무엇인가에 대한 기본 개념부터 시작해야 합니다. Wiki의 설명을 살펴보겠습니다.

코드 복사 코드는 다음과 같습니다.
컴퓨터 공학에서 클로저는 Lexical closure의 약자로 free를 참조하는 함수입니다. 변수. 참조된 자유 변수는 그것이 생성된 환경을 떠난 후에도 함수에 남아 있습니다. 따라서 클로저는 함수와 관련 참조 환경으로 구성된 엔터티라고 말하는 또 다른 방법이 있습니다. 클로저는 런타임에 여러 인스턴스를 가질 수 있으며, 서로 다른 참조 환경과 동일한 함수 조합이 서로 다른 인스턴스를 생성할 수 있습니다.
....

위에 언급된 두 가지 핵심 사항은 자유 변수와 함수입니다. 이 두 가지 키에 대해서는 나중에 설명하겠습니다. "클로저"의 의미에 대해서는 아직 자세히 설명할 필요가 있습니다. 텍스트에서 알 수 있듯이 닫힌 패키지로 생생하게 이해할 수 있습니다. 물론 함수 내부에도 해당 논리가 있습니다. 패키지 내부는 자유입니다. 자유 변수는 패키지와 함께 돌아다닐 수 있습니다. 물론, 이 패키지가 생성된다는 전제가 있어야 합니다.

파이썬 언어를 통해 소개하겠습니다. 클로저는 함수 A를 호출하고 이 함수 A는 함수 B를 반환한다는 의미입니다. 이렇게 반환된 함수 B를 클로저라고 합니다. 함수 A를 호출할 때 전달하는 매개변수는 자유 변수입니다.

예:

def func(name):
 def inner_func(age):
  print 'name:', name, 'age:', age
 return inner_func

bb = func('the5fire')
bb(26) # >>> name: the5fire age: 26

여기에서 func가 호출되면 클로저 - inner_func가 생성되고 클로저는 자유 변수인 name을 보유합니다. 따라서 이는 함수 func의 수명 주기가 끝날 때 변수 이름이 참조되기 때문에 Exists로 유지된다는 의미이기도 합니다. 폐쇄되므로 재활용되지 않습니다.

한 가지 더, 폐쇄는 Python에서 고유한 개념이 아닙니다. 함수를 일급 시민으로 취급하는 모든 언어에는 폐쇄라는 개념이 있습니다. 그러나 클래스가 일급 시민인 Java와 같은 언어에서도 클로저를 사용할 수 있지만 클래스나 인터페이스를 사용하여 구현해야 합니다.

자세한 개념정보는 마지막 참고링크를 참고해주세요.

2. 클로저를 사용하는 이유

위의 소개를 토대로 독자들은 이것이 클래스와 다소 비슷하다고 느낄지 궁금합니다. 유사점은 둘 다 데이터 캡슐화를 제공한다는 것입니다. 차이점은 클로저 자체가 메소드라는 점입니다. 클래스와 마찬가지로 우리는 공통 기능을 재사용하기 위해 프로그래밍할 때(물론 실제 비즈니스를 모델링할 때에도) 일반적인 것을 클래스로 추상화하는 경우가 많습니다. 클로저의 경우에도 마찬가지입니다. 함수별로 세분화된 추상화가 필요한 경우 클로저가 좋은 선택입니다.

이 시점에서 클로저는 읽기 전용 객체로 이해할 수 있습니다. 클로저에 속성을 전달할 수 있지만 실행 인터페이스만 제공할 수 있습니다. 따라서 프로그램에서는 나중에 언급할 데코레이터와 같은 공통 기능을 완성하는 데 도움이 되는 함수 객체(클로저)가 종종 필요합니다.

3. 클로저 사용

Python에서 매우 중요하고 일반적인 사용 시나리오인 첫 번째 시나리오는 데코레이터입니다. Python은 데코레이터를 위한 매우 친숙한 "구문 설탕"을 제공합니다. 이를 통해 장식을 매우 편리하게 사용할 수 있습니다. 간단히 말해서, @ decorator_func를 func 함수에 추가하면 decorator_func(func):

와 동일합니다.
def decorator_func(func):
 def wrapper(*args, **kwargs):
  return func(*args, **kwargs)
 return wrapper

@decorator_func
def func(name):
 print 'my name is', name

# 等价于
decorator_func(func)

이 데코레이터 예에서 클로저(래퍼)는 외부 func 매개변수를 보유하고 외부에서 전달된 매개변수를 허용할 수 있습니다. 수신된 매개변수는 그대로 func에 전달되어 실행 결과로 반환됩니다.

이것은 간단한 예입니다. 자주 사용되는 LRUCache 데코레이터와 같이 여러 개의 클로저를 가질 수 있습니다. 데코레이터는 @lru_cache(expire=500)와 같은 매개변수를 허용할 수 있습니다. 구현은 두 개의 클로저를 중첩하는 것입니다:

def lru_cache(expire=5):
 # 默认5s超时
 def func_wrapper(func):
  def inner(*args, **kwargs):
   # cache 处理 bala bala bala
   return func(*args, **kwargs)
  return inner
 return func_wrapper

@lru_cache(expire=10*60)
def get(request, pk)
 # 省略具体代码
 return response()

클로저에 대해 잘 모르는 학생들은 위의 코드를 이해할 수 있어야 합니다. 이전 인터뷰에서 자주 받았던 질문입니다.

두 번째 시나리오는 클로저의 특징인 "지연 평가"를 기반으로 합니다. 이 애플리케이션은 데이터베이스에 액세스할 때 더 일반적입니다. 예:

# 伪代码示意

class QuerySet(object):
 def __init__(self, sql):
  self.sql = sql
  self.db = Mysql.connect().corsor() # 伪代码

 def __call__(self):
  return db.execute(self.sql)

def query(sql):
 return QuerySet(sql)

result = query("select name from user_app")
if time > now:
 print result # 这时才执行数据库访问

위의 부적절한 예는 클로저를 통한 지연 평가 기능을 보여 주지만 위 쿼리에서 반환된 결과는 함수가 아니라 함수 함수를 포함하는 클래스입니다. 관심이 있다면 Django의 쿼리셋 구현을 살펴보세요. 원리는 비슷합니다.

세 번째 시나리오는 특정 함수의 매개변수를 미리 할당해야 하는 상황입니다. 물론 Python에는 functools.parial에 액세스하는 좋은 솔루션이 이미 있지만 클로저를 사용하여 달성할 수도 있습니다.

def partial(**outer_kwargs):
 def wrapper(func):
  def inner(*args, **kwargs):
   for k, v in outer_kwargs.items():
    kwargs[k] = v
   return func(*args, **kwargs)
  return inner
 return wrapper

@partial(age=15)
def say(name=None, age=None):
 print name, age

say(name="the5fire")
# 当然用functools比这个简单多了
# 只需要: functools.partial(say, age=15)(name='the5fire')

또 다른 억지스러운 예인 것 같지만 클로저 적용을 실천한 것이라고 볼 수 있습니다.

마지막으로 클로저는 이해하기 쉽고 Python에서 널리 사용됩니다. 이 글은 클로저에 대한 요약입니다. 궁금한 점이 있으면 메시지를 남겨주세요.

4. 참고자료

위키피디아-폐쇄

http://stackoverflow.com/questions/4020419/closures-in-python

http://www.shutupandship.com/2012/01/python-closures-explained.html

http://stackoverflow.com/questions/141642/what-limitations-have-closures-in-python-compared-to-언어-x-closures

http://mrevelle.blogspot.com/2006/10/closure-on-closures.html

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.