函数名 闭包 装饰器
函数名的应用(第一对象):
第一对象(first-class object)指
1,可在运行期创建
2,可用作函数参数或返回值
3,可存入变量的实体。
函数的应用:
1,直接打印函数名,得到的是函数的内存地址
def func1():
print(666)
print(func1) # func1没有(),只打印函数名,没有执行
2,函数名可以赋值运算
def func1():
print(666)
f1 = func1
f1() 就等于func1() ,所以执行函数 # 666
3,函数名可以作为函数的参数。
def func1():
print()
def func2(x):
x()
print(555)
func2(func1) ###555
4,函数名可以作为容器类数据类型的元素。
def func1():
print(666)
def func2():
print(222)
def func3():
print(111)
def func4():
print(777)
lis = [func1 ,func2 ,func3 ,func4]
for i in lis:
(i)
dic1 = {
1:func1,
2:func2,
3:func3,
4:func4,
}
dic1[1]()
5,函数名可当函数的返回值。
def func1():
print(666)
def func2(x):
print(222)
return x
ret = func2(func1)
ret() # 222 666
添加
l1 = []
for i in range(1,101):
l1.append('func%d'%i)
print(l1)
闭包:
内层函数对外层函数非全局变量的引用就叫闭包。
在内层函数中访问外层函数的局部变量,叫闭包。这个时候局部变量将会常驻内存。
判断是不是闭包 函数名.__closure__
返回的None则不是闭包,返回的是cell...则是闭包
闭包的目的:让内存永远记住一个变量
闭包有什么用?
当执行一个函数时,如果解释器判断此函数内部闭包存在,这样python就一个机制,闭包的所在的临时名称空间不会随着函数的执行完毕而消失。
def func1():
name = '老男孩'
def inner():
print(name)
inner()
func1()
不是闭包
def func1():
global name
name = '老男孩'
def inner():
print(name)
inner()
func1()
def func1(x):
def inner():
print(name)
inner()
name = '老男孩'
func1(name)
判断是不是闭包:
闭包:
def func1():
name = '老男孩'
def inner():
print(name)
inner()
print(inner.__closure__)
func1() #<cell at 0x0000000001DF65B8: str object at 0x0000000001DF8BD0>
def func1(x):
def inner():
print(x)
inner()
print(inner.__closure__)
name = '老男孩'
func1(name)
非闭包:
def func1(): global name name = '老男孩' def inner(): print(name) inner() print(inner.__closure__) #None func1()
def func():
def func1():
name ="老男孩"
def func2():
nonlocal name
name = "alex"
def func3():
global name
name = "太白"
name = "日天"
func1()
print(name) # 1 日天
func2()
print(name) # 2,alex
func3()
print(name) # 3,alex
func()
print(name) # 4,太白
from urllib.request import urlopen def index(): url = "http://www.xiaohua100.cn/index.html" def get(): return urlopen(url).read() return get xiaohua = index() content = xiaohua() print(content)
装饰器:
装饰器功能:在不改变原函数的基础上,为原函数增加一些额外的功能,log,登录注册,等等.
装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。
装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景
import time
def login():
time.sleep(0.3)
print('洗洗更健康...')
def timmer():
start_time = time.time()
login()
end_time = time.time()
print('此函数的执行时间%s' % (end_time - start_time))
timmer()
import time
def login():
time.sleep(0.3)
print('洗洗更健康...')
# login()
def register():
time.sleep(0.4)
print('洗洗更健康22222...')
# register()
def timmer(f):
start_time = time.time()
f()
end_time = time.time()
print('此函数的执行时间%s' % (end_time - start_time))
timmer(login)
timmer(register)
import time
def login():
time.sleep(0.3)
print('洗洗更健康...')
# login()
def timmer(f):
start_time = time.time()
f()
end_time = time.time()
print('此函数的执行时间%s' % (end_time - start_time))
f1 = login # 将login函数名给了f1
login = timmer # 将timmer函数名给了login
login(f1) # timmer(login)
初级装饰器
import time
def login():
time.sleep(0.3)
print('洗洗更健康...')
# login()
def timmer(f): # f = login函数名
def inner():
start_time = time.time()
f() # login()
end_time = time.time()
print('此函数的执行时间%s' % (end_time - start_time))
return inner
login = timmer(login) # inner 此login是新变量
login() # inner()
name = 'alex'
name = '老男孩'
简单版装饰器 语法糖
import time
def timmer(f): # f = login函数名
def inner():
start_time = time.time()
f() # login()
end_time = time.time()
print('此函数的执行时间%s' % (end_time - start_time))
return inner
@timmer # login = timmer(login) # inner 此login是新变量
def login():
time.sleep(0.3)
print('洗洗更健康...')
login()
@timmer # register = timmer(register)
def register():
time.sleep(0.2)
print('洗洗更健康22...')
login() # inner()
被装饰的函数带参数的装饰器
import time
#
def timmer(f): # f = login函数名
def inner(*args,**kwargs): # args (2, 3)
start_time = time.time()
f(*args,**kwargs) # login() *(2, 3) 2,3
end_time = time.time()
print('此函数的执行时间%s' % (end_time - start_time))
return inner
@timmer # login = timmer(login) # inner 此login是新变量
def login(a,b):
print(a,b)
time.sleep(0.3)
print('洗洗更健康...')
login(2,3) # inner(2,3)
@timmer # register = timmer(register)
def register(a):
time.sleep(0.2)
print('洗洗更健康22...')
register(1) # inner(1)
def func1(x):
x = 0
print(x)
func1(0)
函数带返回值的装饰器 (万能装饰器)
import time
def timmer(f): # f = login函数名
def inner(*args,**kwargs): # args (2, 3)
start_time = time.time()
ret = f(*args,**kwargs) # login() *(2, 3) 2,3
end_time = time.time()
print('此函数的执行时间%s' % (end_time - start_time))
return ret
return inner
@timmer # login = timmer(login) # inner 此login是新变量
def login(a,b):
print(a,b)
time.sleep(0.3)
print('洗洗更健康...')
return 666
print(login(2,3)) # inner(2,3)
简单版装饰器默写:
def wrapper(f):
def inner(*args,**kwargs):
'''执行被装饰函数之前的操作'''
ret = f(*args,**kwargs)
"""执行被装饰函数之后的操作"""
return ret
return inner
语法糖装饰器默写:
def wrapper(f): def inner(*args,**kwargs): ret = f(*args,**kwargs) return ret return inner @wrapper def func(): print(11) func()
装饰器的本质是闭包。
开放封闭原则。
什么是开放封闭原则?
1.对扩展是开放的
为什么要对扩展开放呢?
我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
2.对修改是封闭的
为什么要对修改封闭呢?
就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。
装饰器完美的遵循了这个开放封闭原则。
def wrapper(f): # f = func3函数名
def inner(*args, **kwargs):
print(333)
ret = f(*args, **kwargs) # func3(*(1,2))
print(666)
return ret # 555
return inner
# @wrapper # func1新变量 = wrapper(func1) = inner
# def func1():
# print(111)
# func1() # inner()
# @wrapper # func2(新变量) = wrapper(func2) = inner
# def func2(a, b):
# print(a, b)
# func2(1,2) # inner(1,2)
@wrapper # func3新变量 = wrapper(func3) = inner
def func3(a, b):
print(a, b)
return 555
print(func3(2,3)) # inner(2,3)
posted on 2018-05-28 21:54 liangliang123456 阅读(210) 评论(0) 编辑 收藏 举报