1. 程式人生 > 程式設計 >python閉包及裝飾器執行原理解析

python閉包及裝飾器執行原理解析

一、閉包

閉包從形式上來說是在外部函式中定義內部函式,並且內部函式引用了外部函式的變數,此變數叫做自由變數。

或者說是將組成函式的語句和這些語句的執行環境打包在一起。

閉包滿足的條件:

必須有一個內嵌函式

內嵌函式必須使用外部函式的變數

外部函式的返回值必須是內嵌函式

def closure():
  value = []
  def fun(tmp):
    value.append(tmp)
    return value
  return fun

cc = closure() 
cc(0) #[0] 等同於closure(fun(0))
cc(1) #[0,1]
cc(2) #[0,1,2]

外部函式closure中有變數value和內部函式fun,並且內部函式fun引用了自由變數value,當執行cc = closure()時,就產生了一個閉包fun,該閉包持有隻有變數value,當函式closure生命週期結束後,value依然存在,因為它被閉包引用了。

二、裝飾器

裝飾器其實就是閉包的應用,只不過其傳遞的是函式。

def add_time(fun):
  def wrapper():
    print('time: 12:00')
    return fun()
  return wrapper

def add_format(fun):
  def wrapper():
    print('\n')
    return fun()
  return wrapper

@add_format #等同於demo = add_format(add_time(demo))
@add_time #等同於 demo = add_time(demo)
def demo():
  return 'hello world!'

另外,裝飾器會將demo函式的元資訊丟失,例如__name__等等。

例如demo函式的__name__會由'demo'變成了'wrapper',這時需要用到functools庫,在wrapper函式前加上@functools.wraps(fun):

import functools

def add_time(fun):
  @functools.wraps(fun)
  def wrapper():
    print('time: 12:00')
    return fun()
  return wrapper

def add_format(fun):
  @functools.wraps(fun)
  def wrapper():
    print('\n')
    return fun()
  return wrapper

@add_format #等同於demo = add_format(add_time(demo))
@add_time #等同於 demo = add_time(demo)
def demo():
  return 'hello world!'

例如給任意函式加上列印時間的功能的裝飾器:

def metric(fn):
  start=time.time()
  @functools.wraps(fn)
  def wrapper(*args,**kw):
    end=time.time()
    print('%s executed in %s ms' % (fn.__name__,start-end))
    return fn(*args,**kw)
  return wrapper

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。