-
求一组数据的总分与平均分
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()执行代码查看全部
举报