python笔记(11)--闭包、高阶函数和高阶内置函数
内容目录
- 函数中高级(闭包/高阶函数)
- 内置函数(不常用,但是面试中经常出现)
- 高阶内置函数(map / filter / reduce)
- 内置模块(.py文件)
内容回顾
- 函数基础概念
-
函数的基本结构
-
参数
- 写函数时
- def func(a1,a2):pass
- def func(a1,a2=None):pass
- def func(*args,**kwargs):pass
- 执行函数时
- 位置参数在前 / 关键字参数在后
- 写函数时
-
返回值
- 默认None
- return
-
函数小高级
-
函数可以做变量
def func(): pass v1 = func v1() v2 = [func,func,func] v2[0]()
-
函数可以做参数
def func(arg): v2 = arg() def show(): pass v1 = func(show) #注意返回值
-
python中以函数为作用域
#第一题 for item in range(10): pass print(item) #结果为9 #第二题 item = 10 def func(): for item in range(10): pass print(item) func() #结果为9 #第三题 item = 10 def func(): item = 2 def inner(): print(item) for item in range(10): pass inner() #此函数中item = 9 func() #打印9 #第四题 def func(): for num in range(10): pass v4 = [lambda :num+10,lambda :num+100,lambda :num+100,] result1 = v4[1]() num = 73 result2 = v4[2]() print(result1,result2) func() #输出109,173
-
lambda表达式
-
内置函数(补充)
-
pow:指数
v = pow(2,3) print(v) #2**3,结果为8
-
round:保留小数点后多少位(四舍五入)
v = round(1.325,2) #2代表保留小数点多少位,默认取整 print(v) #1.32
-
-
进制
- bin
- oct
- int
- hex
-
其他(内置函数重点)
- len
- range
- id
- type
- open
-
-
补充:
-
数据类型中的方法到底有没有返回值
-
无返回值
v = [11,22,33] v.append(99) #无返回值
-
仅有返回值
v = 'alec' result = v.split('l') v = {'k1':'v2'} result1 = v.get('k1') result2 = v.keys()
-
有返回+修改数据
v = [11,22,33] result = v.pop()
-
常用需要记住:
- str
- strip,返回字符串
- split,返回列表
- replace,返回字符串
- upper / lower,返回字符串
- join,返回字符串
- list
- append,无
- insert,无
- pop,返回要删除的数据
- remove,无
- find / index,返回索引位置
- dict
- get
- keys
- values
- items
- str
-
-
如果多个函数同时执行时,内部的数据是否会混乱:
- 函数每次运行时都会在内存中开辟一块空间,函数执行完会自动回收内存
- 函数和函数之间调用的时候是互不影响的
- 函数自动回收内存(符合以下条件)
- 函数内部元素无人使用
- 函数执行完毕
内容详细
1.函数中高级(闭包/高阶函数)
1.1 函数可以做返回值
def func():
print("1,2,3")
def bar():
return func
v = bar()
v() #结果为1,2,3
#函数体内没有,往父级里找变量
name = "alec"
def func():
print(name)
def bar():
return func
v = bar()
v() #结果为alec
#################################################
name = "oldboy"
def bar():
name = "alec"
def inner():
print(name)
return inner
v = bar()
v() # 结果为alec
1.2 闭包:
- 为函数创建一块区域(内部变量供自己使用),为他以后执行提供数据
name = "oldboy"
def bar(name):
def inner():
print(name)
return inner
v1 = bar("alec") #{ name=alec,return inner} #闭包
v2 = bar("eric") #{ name=eric,return inner} #闭包
v1() # 结果为alec,执行后回收该块内存
v2() # 结果为eric,执行后回收该块内存
练习题:
#第一题
name = "oldboy"
def bar():
print(name)
def func():
name = "alec"
bar()
func()
#第二题
name = "oldboy"
def func():
name = "alec"
def bar():
print(name)
bar()
func()
#第三题
name = "oldboy"
def func():
name = "alec"
def base():
print(name)
return base #return返回的是base()函数地址
base = func() #调用func()函数,拿到return值
base() #return值调用函数,print输出为alec
面试题:
-
函数在何时被谁创建的
info = [] def func(): print(item) for item in range(10): info.append(func) info[0]()
info = [] def func(i): def inner(): print(i) return inner for item in range(10): info.append(func(item)) info[0]() #结果为0 info[1]() #结果为1 info[4]() #结果为4
1.3 高阶函数
-
把函数当做参数传递
-
把函数当做返回值
注意:对函数进行赋值
1.4 总结
- 函数执行的流程分析(函数到底是谁创建的)
- 闭包概念:为函数创建一块区域并为其维护自己数据,以后执行时方便调用【应用场景:装饰器/SQL Alchemy源码】
- 上面闭包的面试题搞清楚
2.内置函数
编码相关:
-
chr,将十进制数字转换成Unicode编码表中对应的字符串
-
ord,根据字符在Unicode编码中找到其对应的十进制
#将十进制数字转换成Unicode编码表中对应的字符串 v = chr(90) print(v) #结果为 Z #将字符串循环输出每个字符,进行Unicode转换成十进制,然后输出二进制 v = "中国" for item in v: item = ord(item) print(bin(item))
高级的内置函数(map / filter / reduce)
-
map():循环每个元素(第二个参数),然后让每个元素执行函数(第一个参数),将每个函数执行的结果保存到新的列表中,并返回
-
map中第一个参数必须是函数
-
map中第二个参数必须是可迭代类型(可以被for循环的:例如list,dict,tuple,set之类的)
-
然后将函数的返回值添加到新列表中
- py2:直接返回列表
- py3:返回列表的对象,不占内存,需要用时用list强转一下
- 有返回值,原列表不做任何修改
#修改列表中每个数据,每个数据加100 #传统方式: v1 = [11,22,33] for index in range(0,len(v1)): v1[index] += 100 print(v1) #使用map方式: v1 = [11,22,33] def func(arg): return arg + 100 result = map(func,v1) #将函数的返回值添加到列表中 print(list(result)) #使用map + lambda方式: v1 = [11,22,33] result = map(lambda arg:arg + 100,v1) #将函数的返回值添加到列表中 print(list(result))
-
示例图:
-
-
filter():循环每个元素(第二个参数),然后让每个元素执行函数(第一个参数),判断每个函数执行的True / False ,将True或False的值保存到新的列表中,并返回
- 第一个参数必须是函数
- 第二个参数必须是可迭代类型(可以被for循环的:例如list,dict,tuple,set之类的)
- 然后将函数的返回值添加到新列表中
- py2:直接返回列表
- py3:返回列表的对象,不占内存,需要用时用list强转一下
- 有返回值,原列表不做任何修改
#过滤列表中所有的数字,输出结果 #filter方式 v1 = [11,22,33,'asdf','wqer'] def func(arg): if type(arg) == int: return True return False result = filter(func,v1) print(list(result)) #最终结果: #第一个参数func的三元运算写法 def func(arg): return True if type(arg) == int else False #第一个参数func的三元运算写法 def func(arg): return type(arg) == int #filter + lambda + 三元运算 v1 = [11,22,33,'asdf','wqer'] result = filter(lambda arg:type(arg) == int,v1) print(list(result))
-
示例图
-
reduce():
- 必须引用模块 (import functools)
- 第一个参数必须是函数(函数内需要两个以上的参数)
- 第二个参数必须是可迭代类型(可以被for循环的:例如list,dict,tuple,set之类的)
- 然后将函数的返回值添加到新列表中
- 有返回值,原列表不做任何修改
#计算列表中每个数的和 #reduce方法 import functools v1 = [1,2,3,4] def func(x,y): return x + y result = functools.reduce(func,v1) #执行时,首次执行时x,y等于列表中前两个参数,每次循环执行完,x等于之前执行的结果,y等于下一个值 print(result) #结果为10 #reduce + lambda方式: import functools v1 = [1,2,3,4] result = functools.reduce(lambda x, y: x + y, v1) print(result) #将列表中每个字符串拼接起来 import functools v1 = ["ni","hao","ma","alec"] result = functools.reduce(lambda x, y: x + y, v1) print(result) #结果为nihaomaalec
-
示例图
-
面试题:
- 常用的内置函数有哪些?
- filter / map / reduce是什么意思
- 什么是匿名函数?(lambda表达式就是匿名函数)
3.模块
random模块(生成随机数)
应用场景:生成一个随机验证码的函数
- import 导入一个模块
# 注意使用 chr() 方法和random.randint( min , max ),跟unicode编码对应
# random.randint( min , max )生成随机数字
import random
def get_random_code(length=6):
data = []
for item in range(length):
item = random.randint(65, 90)
data.append(chr(item))
return "".join(data)
v = get_random_code()
print(v)
- random.shuffle方法:列表打乱顺序
import random
li = [11,22,33,44,55,66]
random.shuffle(li)
print(li) # 注意,打乱的是原列表。
md5加密:
-
使用hashlib模块
-
不可反解(但是在网上使用撞库(穷举法)可以破解:直接搜md5解密)
import hashlib obj = hashlib.md5() obj.update("123".encode("utf-8")) result = obj.hexdigest() print(result) #使用函数封装: import hashlib def get_md5(data): obj = hashlib.md5() obj.update(data.encode("utf-8")) result = obj.hexdigest() return result user = get_md5("123") print(user)
md5加密加严:
-
加密过程中使用自定义字符添加进加密算法中,无法被反解
import hashlib def get_md5(data): obj = hashlib.md5("sdfjasd".encode("utf-8")) #此md5中可自定义字符 obj.update(data.encode("utf-8")) result = obj.hexdigest() return result user = get_md5("123") print(user)
md5应用:
-
用户登录
import hashlib USER_LIST = [] def get_md5(data): obj = hashlib.md5("sdfjasd".encode("utf-8")) obj.update(data.encode("utf-8")) result = obj.hexdigest() return result def register(): print("*********用户注册*********:") while True: user = input('请创建用户名:') if user == "N": return pwd = input("请创建密码:") USER_LIST.append({"name":user,"password":get_md5(pwd)}) def login(): print("*********用户登录*********:") user = input("请输入用户名:") pwd = input("请输入密码:") for item in USER_LIST: if item["name"] == user and item["password"] == get_md5(pwd): return True register() result = login() if result: print("登录成功") else: print("登录失败")
getpass模块(密码不显示)
(只能在终端运行)
import getpass #导入模块
v = getpass.getpass("请输入密码:") #用户输入时不显示输入内容
if v == "456":
print("登录成功")
else:
print("登录失败")
总结
- 函数
- 基本函数结构(重点,以后98%都在用这个)
- 高级
- 参数
- 闭包
- 内置函数
- 模块
- random
- hashlib
- getpass