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