装饰器后端
你是一家互联网公司的后端攻城狮,大家公司有一个现有函数以下:函数
import time
def add(x,y):
print(x + y)
time.sleep(5)
#add(5,9)
如今TEAM LEADER要让你对函数进行扩展,要求在函数执行以前打印时间,执行以后打印时间,你可能很快就完成了任务,代码以下:spa
import time
def add(x,y):
print(time.time())
print(x + y)
time.sleep(5)
print(time.time())
add(5,9)
此时你信心满满的把这个代码提交给你的TEAM LEADER审核,没成想,没过5分钟,代码就被打回来了, TEAM LEADER给你反馈是,我如今有不少函数须要加这个功能,你的代码虽然实现了功能,可是须要更改各个函数的代码,这直接违反了软件开发中的一个原则“开放-封闭”原则,简单来讲,它规定已经实现的功能代码不容许被修改,但能够被扩展,即:code
封闭:已实现的功能代码块不该该被修改对象
开放:对现有功能的扩展开放开发
BUT ANYWAY,老大要求的这个怎么实现呢?如何在不改原有功能代码的状况下io
加上认证功能呢?咱们以前说太高阶函数,就是把一个函数当作一个参数传给另一个函数,下面就用高阶函数来实现它function
import time
def add(x,y):
print(x + y)
time.sleep(5)
定义一个函数
def show_time(f):
def inner(x,y):#***********这里的参数对应函数f的参数
print(time.time())
f(x,y)
print(time.time())
return inner
则执行show_time(add)返回一个函数对象inner
print(show_time(add))#<function show_time.<locals>.inner at 0x0000000001F00268>
函数对象加括号就会执行函数,则
咱们将show_time(add)返回的值赋给一个变量add
add = show_time(add)
再执行add,就实现功能了
add(1,2)
这样咱们在没有修改原函数的前提下,实现了这个功能,此时无论什么函数须要这个功能,你只要:函数名 = show_time(函数名) ,而后执行这个函数就能够了,为了代码更加简洁,咱们采用注解的方式代替 函数名 = show_time(函数名),只须要在添加功能的函数上方加一行注解:import
import time
def show_time(f):
def inner(x,y):#***********这里的参数对应函数的参数
print(time.time())
f(x,y)
print(time.time())
return inner
@show_time
def add(x,y):
print(x + y)
time.sleep(5)
add(5,9)
@show_time 就至关于 add = show_time(add),@show_time 就是一个装饰器。变量
装饰器有参数的状况
import time
def logger(flag):#这里参数控制是否打印时间
def show_time(f):#这里参数对应函数
def inner(*x, **y): # ***********这里的参数对应函数的参数
start = time.time()
f(*x, **y)
end = time.time()
if flag == True:
print(end - start)
return inner
return show_time
@logger(True)
def add1(*x,**y):
sum = 0
for i in x:
sum += i
print(sum)
time.sleep(4)
add1(1,2,3,4,5,6)
分析:执行 logger(True)返回show_time
因此 @logger(True) 至关于 @show_time,只是多加了一个条件,让使用变得更加灵活。
深浅拷贝
浅拷贝 copy(只拷贝第一层,里面层仍指向原来的对象)
s = [[1, 2], 'aaa', 'bbb']
s2 = s.copy() #第一层的数据都拷贝一份
s2[0][0] =888 #修改后s[0][0]也会变,他们指向同一个对象
s2[1] = 'www' #修改后s[1]不会变,各有各的对象
print(s2) #[[888, 2], 'www', 'bbb']
print(s) #[[888, 2], 'aaa', 'bbb']
深拷贝
须要引入copy模块
import copy
s = [[1, 2], 'aaa', 'bbb']
s3=copy.deepcopy(s) #全部层都复制一份,各是各的,互不影响。
s3[0][1] = 666
print(s3) #[[1, 666], 'aaa', 'bbb']
print(s) #[[1, 2], 'aaa', 'bbb']