一、闭包
1、闭包的三要素
- 外部函数嵌套内部函数
- 外部函数将内部函数返回
- 内部函数可以访问保存外部函数的局部变量
2、闭包函数的作用
在Python中,闭包通常用于实现装饰器、工厂函数以及回调函数等高级编程技术。闭包函数可以帮助我们隐藏实现细节,提高代码的复用性和可维护性。
3、闭包函数的使用
注意:nonlocal相当于global,但是nonlocal使用的是外部函数的局部变量。
闭包函数返回的是内部函数。
返回不是调用,要想实现需要对函数进行调用。
def f1():
print('f1')
i = 0
def f2():
# nonlocal 相当于global,但是nonlocal使用的是外部函数的局部变量
nonlocal i
i += 1
print('f2', i)
# 返回的时候是返回的函数,不是调用,即不用加括号
# 返回的时候还保存了外部函数的局部变量
return f2
f1()
# r就相当于f2(r内部保存了外部变量i)
r = f1()
# 返回的是f2这个函数
print(type(r))
# 调用返回值f2才会执行
r()
二、装饰器
1、装饰器的作用
装饰器是Python中的一种高级编程技术,它可以在不修改原始函数代码的情况下增强函数的功能。装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数。
2、语法糖
- 使用语法糖时闭包写在最上方。
- 使用:@外部函数名。
- 定义在函数上方。
- 装饰器距离函数越近越先修饰。
- 最后不要忘记调用函数。
3、装饰器的语法思路
(1)、写函数
(2)、写闭包
(3)、使用闭包,增加原始函数的功能
(4)、给闭包添加权限校验。
(5)、函数调用
(6)、使用语法糖
例一:
def cart():
print('进入购物车!')
def login_required(f):
def check():
username = input('输入用户名:')
if username == "admin":
f()
else:
print("用户校验失败!")
return check
# 此处cart是函数check
cart = login_required(cart)
cart()
例二:将不改变函数名的赋值更改为语法糖
def login_required(f):
def check():
username = input('输入姓名:')
if username == 'admin':
f()
print('校验成功')
else:
print('校验失败')
return check
@login_required
def mine():
print('我的')
@login_required
def cart():
print('购物车')
def index():
print('首页')
mine()
cart()
例三:随机0-1000以内的500个数字放入列表,使用冒泡排序与选择排序对列表进行升序,编写装饰器统计两个方法的时间开销。
import time
lis = []
for m in range(500):
num = random.randint(0, 1000)
lis.append(num)
l1 = [i for i in lis]
def fun(f):
def sort_num():
start = time.time()
f()
end = time.time() - start
print(end)
return sort_num
@fun
def bubble_sort():
"""
冒泡排序
"""
for i in range(len(lis) - 1):
for j in range(i + 1, len(lis)):
if lis[i] > lis[j]:
lis[i], lis[j] = lis[j], lis[i]
@fun
def select_sort():
"""
选择排序
"""
for i in range(len(l1) - 1):
max_index = i
for j in range(i + 1, len(l1)):
if l1[max_index] > l1[j]:
max_index = j
l1[i], l1[max_index] = l1[max_index], l1[i]
# bubble_sort = fun(bubble_sort)
bubble_sort()
select_sort()
注意:
- 两次排序的列表是同一个列表,而不是排完一遍后的。
- 使用time模块中的time方法获取并计算时间。
- 内部函数调用的是传进去的函数,使用形参调用。
- 不要忘记调用函数。
三、内置函数
1、数学计算
len、max、min、sorted、divmod、pow、round、sum
# len:求可迭代元素长度
print(len('hello'))
# 5
# max:求可迭代元素的最大值
print(max([10, -1, 3 + 11]))
# 14
# 根据后面的条件,得到前面元素的最大值
print(max([{"age": 20}, {"age": 15}, {"age": 50}], key=lambda x: x['age']))
# {'age': 50}
# min:最小值
print(min([{"age": 20}, {"age": 15}, {"age": 50}], key=lambda x: x['age']))
# {'age': 15}
# sorted:按照ascii大小对可迭代元素进行排序
print(sorted('3569238412gujdrg'))
# ['1', '2', '2', '3', '3', '4', '5', '6', '8', '9', 'd', 'g', 'g', 'j', 'r', 'u']
# abs:求绝对值
print(abs(-90))
# 90
# divmod:以元组的形式返回整除结果与余数的结果【divmod(被除数;除数)】
print(divmod(200, 6))
# (33, 2)
# pow:以第一个元素为底,以第二个元素为指数的次方数
print(pow(2, 5))
# 32
# round():四舍五入
print(round(3.14))
# 3
# sum:求和(其中的元素为可迭代的列表)
print(sum([i for i in range(10)]))
print(sum([1, 2, 3, 4, 5, 6, 7]))
# 45
# 28
2、判断是否全假或者全真
all、any
# all:所有元素为真才为真;为空返回的结果也为真
print(all([False, 'False', 10]))
print(all('False'))
print(all(''))
# False
# True
# True
# any:所有元素都为假才为假,空为假
print(any([None, 'a', 0]))
print(any([]))
# True
# False
3、进制转换
oct、hex、bin
# bin:将十进制转化为二进制
print(bin(10))
# oct:将十进制转化为八进制
print(oct(10))
# hex:将十进制转化为十六进制
print(hex(100))
# 0b1010
# 0o12
# 0x64
4、ASCII与字符的转换
chr、ord
# 将ASCII转换为字符
print(chr(97))
# 将字符串转ASCII
print(ord('A'))
# a
# 65
5、局部与全局字典
globals、locals
# locals:以字典的形式返回内置函数
def fun():
i = 10
print(locals())
fun()
# globals:以字典的形式返回全局变量
print(globals())
6、id返回对象唯一标识
# id()
# 返回对象唯一标识
i = 10
print(id(i))