-
求一組數據的總分與平均分
def?my_sum(*arg): ????return?sum(arg) def?my_average(*arg): ????return?sum(arg)/len(arg) def?dec(func): ????def?in_dec(*arg):?#*arg表示返回任意多個無名參數,返回類型為tuple ????????if?len(art)?==?0: ????????????return?0 ????????for?val?in?arg: ????????????if?not?isinstance(val,?int): ????????????????return?0 ????????return?func(*arg) ????return?in_dec my_sum?=?dec(my_sum)?#第一步:將my_sum參數傳入,調用dec函數,返回in_dec,在in_dec函數中,調用my_sum的func函數;第二步:賦值???? print?(my_sum(1,2,3,4,5)) print?(my_average(1,2,3,4,5))
查看全部 -
passline?=?60 def?func(val): ????print?('%x'?%id(val)) ????if?val?>=?passline: ????????print?('pass') ????else: ????????print?('failed') ???????? ????def?in_func(): ????????print?(val) ????in_func() ????return?in_func ???? f?=?func(89) f()?#in_func,引用的計數不為0,會繼續在內存中 #-->打印了兩遍89 print?(f.__closure__)
結果val的id值與f的closure屬性的第一個元素值相等,說明:
如果引用了enclosing作用域的變量,將該變量添加到函數屬性中,當再次查找該變量時,并不是在代碼中查找,而是在函數屬性中查找。
閉包屬性:
closure:內部函數中對enclosing作用域的變量進行引用。
函數實質與屬性:
函數是一個對象
函數執行完成后內部變量回收。如果產生中間變量,變量返回,引用計數不為零,不被回收
函數屬性
函數返回值
def?func_150(val): ????passline?=?90 ????if?val?>=?passline: ????????print?('pass') ????else: ????????print?('failed') ???????? def?func_100(val): ????passline?=?60 ????if?val?>=?passline: ????????print?('pass') ????else: ????????print?('failed') ----------------------------------------------------------- def?set_passline(passline): ????def?cmp(val): ????????if?val?>=?passline: ????????????print?('pass') ????????else: ????????????print?('failed') ????return?cmp???????????? f_100?=?set_passline(60) print(type(f_100))?#-->function print(f_100.__closure__) f_100(89) f_100(59) f_150?=?set_passline(90) f_150(89)
過程:在set_passline函數中傳進passline為60,并且在函數內部定義了cmp函數,該函數引用了enclosing作用域中的passline,因此稱cmp為一個閉包,cmp將passline添加到closure屬性中。閉包的返回值被f_100接收,調用f_100函數進行使用。
閉包的好處:
封裝
代碼復用
查看全部 -
LEGB:優先級L>E>G>B,按照該順序查找
L:local函數內部作用域
E:enclosing函數內部與內嵌函數之間。內嵌函數對于函數內部變量的引用-->閉包
G:global全局作用域。定義的全局變量在全局作用域
B:build-in內置作用域。python解釋器默認導入的變量,例如列表、元組
例子:判斷一個學生的分數是否及格
passline?=?60?#global全局變量 def?func(val):?#引入一個local作用域。在調用func時,val是本地變量 ????passline?=?90?#解釋器先在local作用域查找passline,若沒有,繼續向上查找 ????if?val?>=?passline: ????????print?('pass') ????else: ????????print?('failed') ???????? ????def?in_func(): ????????print?(val)?#val在local中找不到,存在enclosing閉包中 ????in_func() ???? def?Max(val1,?val2):? ????return?max(val1,?val2)?#函數內部引用max方法,存在build-in中 ???? func(89)?#-->failed print?(Max(90,?100))
查看全部 -
LEGB: L>E>G>B 查找順序優先級?
L:local函數內部作用域,是最底層的單個函數里面;?
E:enclosing函數內部與內嵌函數之間,是有內部函數的函數里面;?
G:global 全局作用域,是一個.py文件中;
?B:build-in內置作用域,比如:tuple,list,元組。是所有.py文件中。
查看全部 -
LEGB
L>E>G>B
查看全部 -
1.deco(bar)->in_deco
2.bar = in_deco
3.bar() in_deco() bar()請問這里的bar是在第一次加載的時候已經加入到in_deco中了嘛?否則bar被重新賦值? 原來的bar會找不到
查看全部 -
內部函數中對enclosing作用域的變量進行引用就是閉包
查看全部 -
函數實質與屬性
查看全部 -
閉包概念:
Closure: 內部函數中對 enclosing作用域的變量進行引用
查看全部 -
閉包作用:
1:封裝
2 :代碼復用
查看全部 -
函數作用域優先級
查看全部 -
當看到語法糖@deco的時候:
第一步:調用函數deco(bar),調用后會返回函數對象in_deco
第二步:bar當作了一個參數傳給了deco(),之后被當作enclosing作用域的一個變量,被in_deco()所使用,所以bar被重新賦值:bar = in_deco
第三步:最后調用bar(1,2)整個函數調用流程為:
1、bar()
2、in_deco()
3、bar()
查看全部 -
在設置 my_sum = dec(my_sum)的時候,其實就是把my_sum傳入閉包內,使之成為韓蘇東一個屬性,實質上my_sum = in_dec(*arg)
查看全部 -
查看全部
-
當python看到@deco語法糖時,首先會調用deco(),并返回一個in_deco的新函數對象,然后被要裝飾的函數bar()接收。此時返回的新函數對象in_deco就等于bar()函數。當再調用bar()函數時,實際上是調用in_deco()。在in_deco()函數里面,func()執行代碼查看全部
舉報