目录
0 昨日复习
0.1 函数对象
0.1.1 引用
def f1():
print(147)
f = f1
0.1.2 当作函数的返回值
def f2():
return f1
f3 = f2() #f1
f3()# f1()
0.1.3 当作函数的参数
def f4(func):
func()
f4(f1) # f1()
0.1.4 当作容器的元素
#容器:列表,元组and so on
l = [1,2,3,l1]
l[-1]() #f1()
0.2 函数的嵌套
from math import pi
def circle(radius,action='area'):
if action == 'perimeter':
def perimeter():
return 2*pi*radius
res = perimeter()
else:
def area():
return pi*radius**2
res = area()
return res
res_area = circle(1)
res_perimeter = circle(1,action = 'perimeter')
print(f'area:{res_area}')
print(f'perimeter:{res_perimeter}')
0.3 空间名称与作用域
-
内置名称空间
-
全局名称空间
-
局部名称空间
-
查找顺序:内置名称空间 ---> 全局名称空间 ---> 局部名称空间
-
执行顺序:从当前名称空间开始查找,然后逐步网上,如果当前为局部,则顺序为 局部--->全局--->内置
-
作用域:函数内部的变量和全局的变量,可能命名相同,但不是一个东西
-
global:局部变量声明编程全局变量 (不推荐使用)
-
nonlocal:从内层函数的内部变量声明到外部变量(外层函数的内部变量)(不推荐使用)
1 闭包函数
1.1 何为闭包?
**闭包:闭是封闭(函数内部函数),包是包含(该内部函数对外部作用域而非全局作用域的变量的引用)。闭包指的是:函数内部函数对外部作用域而非全局作用域的引用。 ** (不懂先放着
1.2 代码展示(这就是闭包!)
# this be written by myself ,my understand
def f1(x):
def f2(y):
res = x+y
return res
return f2
f3 = f1(2)
res = f3(3)
print(res)
1.3 闭包的应用
爬虫! 等学完再另外专门学爬虫
2 装饰器
2.1 装饰器是什么?
装饰的东西,工具,装饰的工具
本质也是一个函数,只不过这个函数具有装饰的功能
2.2 为什么要用装饰器?(如懂,
如果我们已经上线了一个项目,我们需要修改某一个方法,但是我们不想修改方法的使用方法,这个时候可以使用装饰器。因为软件的维护应该遵循开放封闭原则,即软件一旦上线运行后,软件的维护对修改源代码是封闭的,对扩展功能指的是开放的。
装饰器的实现必须遵循两大原则:
-
不修改被装饰对象的源代码
-
不修改被装饰对象的调用方式
如懂:后面想起来了再说
2.3 怎么用装饰器?
2.3.1 改变源代码
import time
def time_count():
print("welcome to time_count")
start_time = time.time()
time.sleep(3)
end_time = time.time()
print(f'休眠时间:{end_time - start_time}')
time_count()
time_count()
2.3.2 编写重复代码
import time
def index():
print('welcome to index')
time.sleep(2)
def f2():
print('welcome to f2')
time.sleep(2)
start = time.time()
index()
end = time.time()
print(f'index run time is {start - end}')
start = time.time()
f2()
end = time.time()
print(f'f2 run time is {start - end}')
2.3.3 第一种传参方式:改变调用方式
import time
def index():
print('welcome to index')
time.sleep(2)
def time_count(func):
start = time.time()
func()
end = time.time()
print(f'{func} time is {end - start}')
time_count(index)
2.3.4 第二种传参方式:报给函数(外包)
import time
def index():
print('welcome to index')
time.sleep(2)
def time_count(func):
def wrapper():
start = time.time()
func()
end = time.time()
print(f'{func} time is {end - start}')
return wrapper
f = time_count(index)
f()
声明:上述过程我都懂,但目前以我垃圾的认知,真不知道好用到哪了*-*
2.4 完善装饰器
如果原始的index()方法需要传参,那么我们之前的装饰器是无法实现该功能的,由于有wrapper()=index(),所以给wrapper()方法传参即可。
import time
def index():
print('welcome to index')
time.sleep(1)
return 123
def home(name):
print(f"welcome {name} to home page")
time.sleep(1)
return name
def time_count(func):
# func = 最原始的index
def wrapper(*args, **kwargs): # 这里给wrapper 加了这俩玩意,因此能够接受任意数据的参数作为形参
start = time.time()
res = func(*args, **kwargs) # 这里就要求time_count函数接收的函数必须为有参函数,即home,不能为index
end = time.time()
print(f"{func} time is {start-end}")
return res # 即此时函数wrapper(*args, **kwargs) 会得到返回值 res,即func(*args,**kwargs),
# 即wrapper(*args, **kwargs) = func(*args,**kwargs)
return wrapper # 即此时函数执行time_count(func) = wrapper = func
home = time_count(home) # 即home = time_count(home) = wrapper = home
res = home('egon') # 此时home 变了,被wrapper取代了
print(f"res: {res}")
in short:这就是装饰器的常见用法。用于在不修改原始函数代码的情况下,给函数添加额外的功能。
说实话,本来就是在稀里糊涂的跟着水导的博客一个接着一个代码敲,边敲边理解,但到理解到最后有一个疑问,好像原来的home函数不在了,被取代了,但又不确实对不对,去ai了一下,果然是的被wrapper取代了,接着最后一句话瞬间明白了,有一种醍醐灌顶的感觉,^-^
2.5 装饰器模板
def deco(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
return res
return wrapper
2.6 装饰器语法糖 +
在被装饰函数正上方,并且是单独一行写上@装饰器名
userinfo_dict = {'sch':147}
is_login_list = False #定义成可变类型或着global使其可以修改
def login(func):
def wrapper(*args,**kwargs):
global is_login_list
if not is_login_list:
username = input("请输入你的用户名>>>")
pwd = int(input("请输入你的密码>>>"))
if username in userinfo_dict and pwd == userinfo_dict.get(username):
print('登陆成功')
is_login_list = True
res = func(*args,**kwargs)
return res
print("傻逼来老子这里吃霸王餐!")
else:
res = func(*args,**kwargs)
return res
return wrapper
@login
def shopping():
print('with shopping')
def pay():
print('with pay')
标签:闭包,12,函数,res,func,time,print,Day,def
From: https://www.cnblogs.com/chsun12/p/18502902