1. 程式人生 > >Python函式的作用域、閉包、裝飾器

Python函式的作用域、閉包、裝飾器

Python函式的作用域
LEGB: L>E>G>B 查詢順序優先順序
L:local函式內部作用域,是最底層的單個函式裡面;
E:enclosing函式內部與內嵌函式之間,是有內部函式的函式裡面;
G:global 全域性作用域,是一個.py檔案中;
B:build-in內建作用域,比如:tuple,list,元組。是所有.py檔案中。
 
Python函式的閉包
#定義:如果在一個內部函式裡,對在外部作用域(但不是在全域性作用域)的變數進行引用,那麼內部函式就被認為是閉包(closure)
分解來說,包含下面3個條件:
1) 需要函式巢狀, 就是一個函式裡面再寫一個函式.
2) 外部函式需要返回一個內部函式的引
3) 外部函式中有一些區域性變數, 並且, 這些區域性變數在內部函式中有使用
一些概念:
1)自由變數: 外部函式中定義的區域性變數, 並且在內部函式中被使用
2) 閉包: 那個使用了自由變數並被返回的內部函式就稱為閉包
#支援閉包的語言有這樣的特性:
1)函式是一階值(First-class value),即函式可以作為另一個函式的返回值或引數,還可以作為一個變數的值
2)函式可以巢狀定義,即在一個函式內部可以定義另一個函式
#程式碼示例(點開編輯檢視)
#coding:utf-8
#閉包的好處:1實現封裝,2實現程式碼複用
def func(val):
  def func2(score):  #閉包func2
        if score >= val:
            print('及格')
        else:
            print('不及格')
    return func2
f_100 = func(60)  # 60及格100滿分
f_150 = func(90)  # 90及格150滿分
f_100(89)
f_150(89)
閉包會保留來自外圍作用域變數的資訊。
Python 中函式物件都擁有一個 __closure__ 屬性。
__closure__ 物件返回一個由 cell 物件組成的元組,cell 物件記錄了定義在外圍作用域的變數資訊。
對於那些不是閉包的函式物件來說,__closure__ 屬性值為 None。
def get_sum(val):
    return sum(val)
def get_div(val):
return float(sum(val)) / float(len(val))def dec(func):
def in_dec(*arge):
# print('in_dec')if len(arge) == 0:
return 0for val in arge:
if not isinstance(val, int):
return 0return func(arge) return in_decf_get_sum = dec(get_sum) # f_get_sum=in_dec -->in_dec(*arge) -->func(arge)
f_get_div = dec(get_div)
print(f_get_sum(1, 2, 3, 4, 5))
print(f_get_div(1, 3, 5, 7, 9))
print(f_get_sum(1, 3, 5, 7, 9, '6'))
print(f_get_div(1, 3, 5, 7, 9, '6'))
Python函式的裝飾器
 裝飾器就是對閉包的使用
1 裝飾器用來裝飾函式
2 返回一個函式物件
3 被裝飾函式識別符號指定返回的函式物件
4 語法糖 @deco
    def in_dec(*arge):
        # print('in_dec')
if len(arge) == 0:
            return 0
for val in arge:
            if not isinstance(val, int):
                return 0
return func(arge)
    return in_dec
@dec  #@dec相當於:get_sum=dec(func)->dec(func)返回in_dec則get_sum=in_dec
def get_sum(val):
    return sum(val)
@dec
def get_div(val):
    return float(sum(val)) / float(len(val))
print(get_sum(1,3,5,7,9))
print(get_div(1,3,5,7,9))
def dec(func):