一,闭包
内部的函数引用了外部函数的变量
def f1(b):
def f2():
print(b) #内部函数引用了外部函数的变量b
f2()
f1()
我们都知道函数内的变量我们要想在函数外部用,可以直接返回这个变量,那么我们想在函数外部调用函数内部的函数
直接就把这个函数的名字返回就好了。
def func():
name = 'QQQ'
def inner():
print(name) #QQQ
return inner
f = func()
f()
判断闭包函数的方法__closure__
#输出的__closure__有cell元素 :是闭包函数 def func(): name = 'eva' def inner(): print(name) print(inner.__closure__) return inner f = func() f() #输出的__closure__为None :不是闭包函数 name = 'egon' def func2(): def inner(): print(name) print(inner.__closure__) return inner f2 = func2() f2()
闭包的嵌套
def wrapper():
money = 1000
def func():
name = 'alex'
def inner():
print(name,money) #alex 1000
return inner
return func
f = wrapper()
i = f()
i()
内部函数返回一个值到全局
def f1(): #从内部函数返回一个值到全局
b = 10
def f2():
return b
return f2()
print(f1()) #10
闭包函数获取网络应用
from urllib.request import urlopen
def get(url):
return urlopen(url).read()
print(get('http://www.cnblogs.com/weiwu1578/articles/7772732.html'))
二,装饰器
装饰器的作用
在不改变函数的调用方式的情况下,给函数的前后添加新的功能
装饰器的形成过程
简单版
关于时间
import time #模块
def timmer(func):
def inner():
start_time = time.time() #程序起始时间
time.sleep(1) #程序休停时间
func()
end_time = time.time() #程序结束时间
print('=====%s=====' % (end_time - start_time))
return inner
def func():
print('老铁666老铁')
func = timmer(func)
func()
结果: 老铁666老铁
=====1.0008132457733154=====
装饰器----语法糖,万能的装饰
def timmer(qqxing): #timmer是装饰器的名字,传入的参数就是被装饰的函数
def inner(*args,**kwargs): #在装饰器中需要定义一个内部函数
print('调用func之前')
ret = qqxing(*args,**kwargs) #被装饰的函数,并且要执行
print('调用func之后')
return ret
return inner #将内部函数的名字返回
@timmer #语法糖 func = timmer(func)
def func(name):
print('%s老铁666'%(name))
return 1111111111
ret = func('俊杰')
print('result : %s'%ret)
结果
调用func之前
俊杰老铁666
调用func之后
result : 1111111111
总结:
装饰器的本质:一个闭包函数
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
装饰带参数的函数:
import time
def timer(func):
def inner(*args,**kwargs):
start = time.time()
re = func(*args,**kwargs)
print(time.time() - start)
return re
return inner
@timer #==> func1 = timer(func1)
def func1(a,b):
print('in func1')
@timer #==> func2 = timer(func2)
def func2(a):
print('in func2 and get a:%s'%(a))
return 'fun2 over'
func1('aaaaaa','bbbbbb')
print(func2('aaaaaa'))
结果:
in func1
0.0
in func2 and get a:aaaaaa
0.0
fun2 over
装饰带参数且有返回值的函数
import time
def timer(func):
def inner(*args,**kwargs):
# start = time.time()
re = func(*args,**kwargs)
# print(time.time() - start)
return re
return inner
@timer #==> func2 = timer(func2)
def func2(a):
print('in func2 and get a:%s'%(a))
return 'fun2 over'
func2('bbbbb')
print(func2('aaaaaa'))
结果:
in func2 and get a:bbbbb
in func2 and get a:aaaaaa
fun2 over
开放封闭原则
1.对扩展是开放的
为什么要对扩展开放呢?
我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
2.对修改是封闭的
为什么要对修改封闭呢?
就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。
装饰器完美的遵循了这个开放封闭原则。
装饰器的主要功能和装饰器的固定结构
装饰器的主要功能:
在不改变函数调用方式的基础上在函数的前、后添加功能。
装饰器的固定格式:
def timer(func):
def inner(*args,**kwargs):
'''执行函数之前要做的'''
re = func(*args,**kwargs)
'''执行函数之后要做的'''
return re
return inner
有成千上万个函数使用了一个装饰器,把这些装饰器都取消掉
def outer(flag):
def timer(func):
def inner(*args,**kwargs):
if flag:
print('''执行函数之前要做的''')
re = func(*args,**kwargs)
if flag:
print('''执行函数之后要做的''')
return re
return inner
return timer
@outer(False)
def func():
print(111)
func()