Python函数式编程-动态参数、函数实战与Python常用库
一、动态参数
1、什么时候使用动态参数?
(1):当函数的形式参数个数不确定时;
(2):当函数的形式参数数据类型不确定时。
2、在Python中,“*”:代表的是元组,“**”:代表的是字典。
3、应用
应用1:
1 def func(*args,**kwargs): 2 print(args) 3 print(type(args)) 4 print("\n") 5 print(kwargs) 6 print(type(kwargs)) 7 func(a=2) 8 func(**{"name":"lucy","age":23,"city":"xi'an"}) 9 func("a","b","c") 10 func(["a","b","c"]) 11 func([x for x in range(3)]) 12 func((1,2,3,4))
运行结果如下:
() <class 'tuple'> {'a': 2} <class 'dict'> () <class 'tuple'> {'name': 'lucy', 'age': 23, 'city': "xi'an"} <class 'dict'> ('a', 'b', 'c') <class 'tuple'> {} <class 'dict'> (['a', 'b', 'c'],) <class 'tuple'> {} <class 'dict'> ([0, 1, 2],) <class 'tuple'> {} <class 'dict'> ((1, 2, 3, 4),) <class 'tuple'> {} <class 'dict'> Process finished with exit code 0
应用2:在接口测试中会用到,接口测试中有多个接口,有时候请求需要4个参数,有时候请求需要5个参数,有时候请求需要6个参数,有时候一个也不需要。
假设我们分别请求需要1个参数、3个参数:
按照我们原先的做法,我们会这样:
1 def data1(): 2 return{} #1个参数 3 print(data1()) 4 5 def data2(): 6 return{"name":"lucy","age":23,"city":"xi'an"} #3个参数 7 print(data2())
运行结果如下:
{} {'name': 'lucy', 'age': 23, 'city': "xi'an"} Process finished with exit code 0
这样显然很麻烦,我们需要输入2个函数:data1()和data2(),而我们如果使用动态参数这种方法会简洁许多。动态参数法如下:
1 def data(**kwargs): 2 return kwargs 3 print(data()) 4 print(data(**{"name":"lucy","age":23,"city":"xi'an"}))
#本身就是字典型,想要它返回输出也是字典,那么只需给它前面添加“**”即可。
运行结果如下:
{} {'name': 'lucy', 'age': 23, 'city': "xi'an"} Process finished with exit code 0
二、函数实战
要求: 1、注册登录 2、登陆成功后,显示个人主页 3、通过控制台的模式来交互
代码如下:
1-1:注册页面
1 def registred(): 2 username=input("What is your name?") 3 password=input("Please write your password:") 4 temp=username+"-"+password 5 with open(file="login.txt",mode="w",encoding="UTF-8") as f: 6 f.write(temp) 7 registred()
运行结果如下:
What is your name?Lucy Please write your password:17166230 Process finished with exit code 0
1-2:登陆页面
1 def login(): 2 username=input("What is your name?") 3 password=input("Please write your password:") 4 with open(file="login.txt",mode="r",encoding="UTF-8") as f: 5 lists=f.read().split("-") 6 if username==lists[0] and password==lists[1]: 7 return True 8 else: 9 print("登陆失败,请重新登陆!") 10 print(login())
运行结果1:
What is your name?Lucy Please write your password:17166230 True Process finished with exit code 0
运行结果2:
What is your name?Rose Please write your password:20220620 登陆失败,请重新登陆! Process finished with exit code 0
2:显示个人主页面
1 def profile(): 2 with open(file="login.txt",mode="r",encoding="UTF-8") as f: 3 lists=f.read().split("-") 4 print("Welcome to {person} page!".format(person=lists[0])) 5 profile()
运行结果如下:
Welcome to Lucy page!
Process finished with exit code 0
3:通过控制台的模式来交互
1 #公共部分,封装思想,减少重复代码书写 2 def out(): 3 username=input("What is your name?") 4 password=input("Please write your password:") 5 return username,password 6 #注册 7 def registered(): 8 username,password=out()#公共部分 9 temp=username+"-"+password 10 with open(file="login.txt",mode="w",encoding="UTF-8") as f: 11 f.write(temp) 12 # 登陆 13 def login(): 14 username, password = out() #公共部分 15 with open(file="login.txt",mode="r",encoding="UTF-8") as f: 16 lists=f.read().split("-") 17 if username==lists[0] and password==lists[1]: 18 return True 19 else: 20 print("登陆失败,请重新登录!") 21 #访问主页面 22 def profile(): 23 with open(file="login.txt",mode="r",encoding="UTF-8") as f: 24 lists=f.read().split("-") #字符串转列表,字符串的拆分:.split()数据类型是列表 25 print("Welcome to {person} page!".format(person=lists[0])) 26 #主函数 27 def principal(): 28 while True: 29 try: #异常处理 30 f=int(input("1、注册,2、登陆\n")) 31 if f==1: 32 registered() 33 elif f==2: 34 if login()==True: 35 profile() 36 else: 37 print("Please login again") 38 else: 39 break 40 except:continue 41 if __name__ == '__main__':#作为程序的入口,执行函数 42 principal()
运行结果如下:
1、注册,2、登陆 1 What is your name?Lucy Please write your password:17166230 1、注册,2、登陆 2 What is your name?Rose Please write your password:20220620 登陆失败,请重新登录! Please login again 1、注册,2、登陆 2 What is your name?Lucy Please write your password:17166230 Welcome to Lucy page! 1、注册,2、登陆 3 Process finished with exit code 0
三、Python常用库
1、模块与包
在Python里面,每一个Python文件都可以成为一个模块,在一个包中可以包含多个Python文件,包与模块之间的关系如下:
1-1:如果是同包之间的模块调用,即这2个模块文件在同一个包下面,它的方式为:
假设我命名的包和文件是这样的:
在index.py和logout.py之间相互调用:
index.py文件如下:
1 name="Lucy" 2 def login(): 3 print("login success!") 4 a="Hello world!"
logout.py文件如下:
from package.package.module import * #包里的包里的模块
1 from module.index.index import * #包里的包里的模块 2 print(name) 3 login() 4 print(a)
运行结果如下:
Lucy
login success!
Hello world!
Process finished with exit code 0
1-2:如果是不同包之间的模块调用,即这2个模块文件不在同一个包下面,它的方式为:
假设我命名的包和文件是这样的:
在index.py和logout.py之间相互调用:
index1.py文件如下:
1 name="Lucy" 2 def login(): 3 print("login success!") 4 a="Hello world!"
logout.py文件如下:
from package.module import * #导入全部的,包里的模块
1 from module.index1 import * #包里的模块 2 print(name) 3 login() 4 print(a)
运行结果如下:
Lucy
login success!
Hello world!
Process finished with exit code 0
2、Python常用库
在Python中,可分为两类:
2-1:标准库:就是安装完Python解释器后,这些库就已经存在了,不需要单独的再次安装。即解释器自带的库。
2-2:第三方库:需要单独的进行安装。安装方式主要分为两类:一类是在线安装(建议),另一类是离线安装。即有组织或者是个人编写好的库,可以供全球的程序员使用。
安装:pip install 库的名称
卸载:pip uninstall 库的名称
常见的框架:
Django:WEB全栈开发框架
Flask:轻量级的WEB开发框架
Selenium:UI自动化测试框架
Requests:接口测试框架
2-3:随机数:random库
1 import random #使用第三方的库或者标准库 2 print(random.randrange(1,5,2)) 3 print(random.randint(10,12))
运行结果如下:
1
11
Process finished with exit code 0
3、OS库实战
3-1:获取路径
import os
#获取当前路径 print(os.path.dirname(__file__)) #获取当前路径的上一级路径 print(os.path.dirname(os.path.dirname(__file__))) #获取当前路径的上上一级路径 print(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
3-2:路径的拼接
eg1:新建一个Data文件,里面新建一个file文件log,并且log里输入“Hello World!”
在module包里新建“os学习.py"
最终将两者的路径拼接成”D:\test\code\testDev\data\log“形式
1 import os 2 print(os.path.dirname(__file__)) #运行结果:D:\test\code\testDev\module 3 print(os.path.dirname(os.path.dirname(__file__))) #运行结果:D:\test\code\testDev 4 base_dir=os.path.dirname(os.path.dirname(__file__)) #转换成文件形式 5 print(os.path.join(base_dir,"data","log")) #使用.join拼接,,#运行结果:D:\test\code\testDev\data\log 6 filePath=os.path.join(base_dir,"data","log") #转换成文件形式 7 with open(file=filePath,mode="r",encoding="UTF-8") as f: #将拼接好的读取出来 8 print(f.read())
运行结果如下:
D:\test\code\testDev\module
D:\test\code\testDev
D:\test\code\testDev\data\log
Hello World!
Process finished with exit code 0
eg2:新建一个Data文件,里面新建一个file文件log,并且log里输入“Hello World!
在module包里新建"index包"再在此包里创建"os学习.py"
最终将两者的路径拼接成”D:\test\code\testDev\data\log“形式
1 import os 2 print(os.path.dirname(__file__)) #运行结果D:\test\code\testDev\module\index 3 print(os.path.dirname(os.path.dirname(__file__))) #运行结果D:\test\code\testDev\module 4 print(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) #运行结果D:\test\code\testDev 5 base_dir=os.path.dirname(os.path.dirname(os.path.dirname(__file__))) #转换成文件形式 6 print(os.path.join(base_dir,"data","log")) #使用.join拼接,,#运行结果:D:\test\code\testDev\data\log 7 filePath=os.path.join(base_dir,"data","log") #转换成文件形式 8 with open(file=filePath,mode="r",encoding="UTF-8") as f: #将拼接好的读取出来 9 print(f.read())
运行结果如下:
D:\test\code\testDev\module\index
D:\test\code\testDev\module
D:\test\code\testDev
D:\test\code\testDev\data\log
Hello World!
Process finished with exit code 0
3-3
3-3-1:获取操作系统:os.name
1 import os 2 print(os.name)
运行结果如下:
nt
Process finished with exit code 0
3-3-2:判断目录是否存在:os.path.exists()
1 import os 2 print(os.path.exists("C:\Program Files\Google"))
运行结果如下:
True
Process finished with exit code 0
3-3-3:判断是否是文件:os.listdir()
1 import os 2 print(os.path.exists("C:\Program Files\Google")) 3 for item in os.listdir("C:\Program Files\Google") 4 print(item)
运行结果如下:
True
Chrome
GoogleUpdater
Process finished with exit code 0
事实上也确实如此:
3-3-4:”ping“命令来看是否可以访问网址:os.system()
1 import os 2 print(os.system("ping www.baidu.com))
运行结果如下:
���� Ping www.baidu.com [14.215.177.39] ���� 32 �ֽڵ�����: ���� 14.215.177.39 �Ļظ�: �ֽ�=32 ʱ��=35ms TTL=54 ���� 14.215.177.39 �Ļظ�: �ֽ�=32 ʱ��=33ms TTL=54 ���� 14.215.177.39 �Ļظ�: �ֽ�=32 ʱ��=51ms TTL=54 ���� 14.215.177.39 �Ļظ�: �ֽ�=32 ʱ��=33ms TTL=54 14.215.177.39 �� Ping ͳ����Ϣ: ���ݰ�: �ѷ��� = 4���ѽ��� = 4����ʧ = 0 (0% ��ʧ)�� �����г̵Ĺ���ʱ��(�Ժ���Ϊ��λ): ��� = 33ms��� = 51ms��ƽ�� = 38ms 0 Process finished with exit code 0
4、time实战
time模块提供了各种与时间有关系的库,具体time的案例实战如下:
1 import time as t 2 #操作时间 3 #获取时间戳 4 print("获取当前时间的时间戳:",t.time()) #用的较多 5 print("返回当前的字符串:",t.ctime()) 6 print("时间戳转为字符串:",t.ctime(t.time())) 7 print("本地化:",t.localtime(t.time()).tm_year) 8 print("本地化:",t.localtime(t.time()).tm_mon) 9 print("本地化:",t.localtime(t.time()).tm_mday) 10 print("中国人的时间:",t.strftime("%y-%m-%d %H:%M:%S",t.localtime())) #用的较多 11 t.sleep(10) #休眠10S 12 print("中国人的时间:",t.strftime("%y-%m-%d %X",t.localtime())) # %H:%M:%S等价于%X 13 print("中国人的时间:",t.strftime("%y-%m-%d %x",t.localtime()))
运行结果如下:
获取当前时间的时间戳: 1655806814.1414294 #在每次重新运行的时候,所获取的当前时间戳是不一样的! 返回当前的字符串: Tue Jun 21 18:20:14 2022 时间戳转为字符串: Tue Jun 21 18:20:14 2022 本地化: 2022 本地化: 6 本地化: 21 中国人的时间: 22-06-21 18:20:14 中国人的时间: 22-06-21 18:20:24 中国人的时间: 22-06-21 06/21/22 Process finished with exit code 0
5、hashilb库实战
hashilb里面主要会涉及到md5的加密算法,其中md5是一种加密方式,md5加密后基本破解不了。
实战如下:
需求:接口测试
a:针对字典进行排序
b:把排序后的字典处理成key1=value1&key1=value2
c:进行md5加密,加密后就是密钥
1 import hashlib 2 from urllib import parse #urllib是网络爬虫 3 import time 4 def sign(): 5 dict1={"name":"Lucy","age":23,"city":"xi'an","time":time.time()}#加入时间戳可以使我们的项目更具安全性,不易破解! 6 #字典排序 7 data=dict(sorted(dict1.items(),key=lambda item:item[0])) 8 print(data) 9 #把排序后的结果处理成key1=value1&key1=value2,编码:就是把str的数据类型转为bytes的数据类型的过程,使⽤到的关键字是encode. 10 data2=parse.urlencode(data) 11 print(data2) 12 m=hashlib.md5() #进行md5的加密 13 m.update(data2.encode("UTF-8")) 14 print("加密后的结果信息:\n",m.hexdigest()) 15 sign()
运行结果如下:
{'age': 23, 'city': "xi'an", 'name': 'Lucy', 'time': 1655807662.5053277} age=23&city=xi%27an&name=Lucy&time=1655807662.5053277 加密后的结果信息: 03488e7609a6606545acf584f26c6ce7 Process finished with exit code 0
6、Datetime实战
相比于time的模块,datetime也是表示时间的,但是会更加的直观,案例如下:
1 import datetime 2 import time 3 #datetime也是表示时间,是对time的二次封装 4 #获取当前时间 5 print(datetime.datetime.now()) 6 #在当前时间基础上增加或者减少 7 print(datetime.datetime.now()-datetime.timedelta(days=10)) 8 print(datetime.datetime.now()-datetime.timedelta(minutes=10)) 9 print(datetime.datetime.now()-datetime.timedelta(seconds=10)) 10 print(datetime.datetime.now()+datetime.timedelta(days=10)) 11 print(datetime.datetime.now()+datetime.timedelta(minutes=10)) 12 print(datetime.datetime.now()+datetime.timedelta(seconds=10)) 13 #将时间戳转换为时间 14 print(datetime.datetime.fromtimestamp(time.time()))
运行结果如下:
2022-06-21 18:38:35.734726
2022-06-11 18:38:35.734726
2022-06-21 18:28:35.734726
2022-06-21 18:38:25.734726
2022-07-01 18:38:35.734726
2022-06-21 18:48:35.734726
2022-06-21 18:38:45.734726
2022-06-21 18:38:35.734727
Process finished with exit code 0
7、JSON库实战(很重要)
在接口测试中应用较多
7-1:序列化:【简单地说就是把Python对象(字典,列表,元组)转为字符串的过程。】把内存⾥的数据类型转为字符串的数据类型,使能够存储到硬盘或通过网络传输到远程,因为硬盘或者网络传输时只接受bytes的数据类型。序列化使用函数:json.dumps()
反序列化:【简单地说就是把把字符串转为Python对象(字典,列表,元组)的过程。】反序列化使用函数:json.loads()
7-1-1:字典的序列化和反序列化
1 import json 2 #字典的序列化 3 dict1={"name":"Lucy","age":23,"city":"xi'an"} 4 dict1_str=json.dumps(dict1,indent=True,ensure_ascii=False) 5 dict1_str=json.dumps(dict1,indent=True,ensure_ascii=True) 6 print(dict1_str) 7 print(type(dict1_str)) 8 #字典的反序列化 9 str_dict1=json.loads(dict1_str) 10 print(str_dict1) 11 print(type(str_dict1))
运行结果如下:
{ "name": "Lucy", "age": 23, "city": "xi'an" } <class 'str'> {'name': 'Lucy', 'age': 23, 'city': "xi'an"} <class 'dict'> Process finished with exit code 0
注意:字典的序列化的以下情况:
NO1:
1 import json 2 dict1={"name":"Lucy","age":23,"city":"xi'an"}
#无中文,不会出现乱码现象,因此不论"ensure_ascii"是等于"True"还是"False",都不会影响。 3 dict1_str=json.dumps(dict1,indent=True,ensure_ascii=False) 4 dict1_str=json.dumps(dict1,indent=True,ensure_ascii=True) 5 print(dict1_str) 6 print(type(dict1_str))
运行结果如下:
{ "name": "Lucy", "age": 23, "city": "xi'an" } <class 'str'> Process finished with exit code 0
NO2:字典的序列化-乱码现象(ensure_ascii)
1 import json 2 dict1={"name":"黛西","age":23,"city":"xi'an"} #有中文,注意ASCLL码转换 3 #dict1_str=json.dumps(dict1,indent=True,ensure_ascii=True) #乱码现象 4 #Python默认是ASCLL码,“ensure_ascii=False”转换为我们认识的中文 5 dict1_str=json.dumps(dict1,indent=True,ensure_ascii=False) #正确 6 print(dict1_str) 7 print(type(dict1_str))
运行结果如下:
{ "name": "黛西", "age": 23, "city": "xi'an" } <class 'str'> Process finished with exit code 0
NO3:字典的序列化-缩进现象(indent)
1 import json 2 dict1={"name":"黛西","age":23,"city":"xi'an"} #有中文,注意ASCLL码转换 3 dict1_str=json.dumps(dict1,indent=True,ensure_ascii=True) #乱码现象 4 Python默认是ASCLL码,“ensure_ascii=False”转换为我们认识的中文 5 dict1_str=json.dumps(dict1,indent=False,ensure_ascii=False) #错误的缩进 6 print(dict1_str) 7 print(type(dict1_str))
运行结果如下:
{ "name": "黛西", "age": 23, "city": "xi'an" } <class 'str'> Process finished with exit code 0
7-1-2:元组的序列化和反序列化
1 import json 2 #元组的序列化 3 tuple1=("Python","Java") 4 tuple1_str=json.dumps(tuple1) 5 print(tuple1_str) 6 print(type(tuple1_str)) 7 #元组的反序列化 8 str_tuple1=json.loads(tuple1_str) 9 print(str_tuple1) 10 print(type(str_tuple1))
运行结果如下:(注意它的运行结果的不同)
["Python", "Java"] #列表 <class 'str'> ['Python', 'Java'] #列表 <class 'list'> Process finished with exit code 0
7-1-3:列表的序列化和反序列化
1 import json 2 #列表的序列化 3 lists=[x for x in range(5)] 4 list_str=json.dumps(lists) 5 print(list_str) 6 print(type(list_str)) 7 #列表的反序列化 8 str_list=json.loads(list_str) 9 print(str_list) 10 print(type(str_list))
运行结果如下:
[0, 1, 2, 3, 4] <class 'str'> [0, 1, 2, 3, 4] <class 'list'> Process finished with exit code 0
7-2:针对文件的序列化和反序列化
序列化:把第三方的内容写到文件中 dump()
反序列化:从文件中读取数据 load()
7-2-1:先新建一个空白"json.txt"文本
1 import json 2 dict1={"name":"黛西","age":23,"city":"xi'an"} #假设为第三方的内容 3 json.dump(dict1,open(file="json.txt",mode="w",encoding="UTF-8"),ensure_ascii=False)
#写到文件中dump() 4 data=(json.load(open(file="json.txt",mode="r",encoding="UTF-8")))
#读取数据load() 5 print(data) 6 print(type(data))
运行结果如下:
{'name': '黛西', 'age': 23, 'city': "xi'an"} <class 'dict'> Process finished with exit code 0
会发现写的是字典型,对应的也会输出字典型!
打开空白"json.txt"文本,内容如下:
{"name": "黛西", "age": 23, "city": "xi'an"}
7-2-2:进一步优化“通过控制台的模式来交互”
1 #3、通过控制台的模式来交互 2 import json 3 #公共部分,封装思想 4 def out(): 5 username=input("What is your name?") 6 password=input("Please write your password:") 7 return username,password 8 #注册 9 def registered(): 10 username,password=out() 11 temp=username+"-"+password 12 # with open(file="login.txt",mode="w",encoding="UTF-8") as f: 13 # f.write(temp) 14 json.dump(temp,open(file="login.txt",mode="w",encoding="UTF-8")) 15 # registered() 16 # 登陆 17 def login(): 18 username, password = out() 19 # with open(file="login.txt",mode="r",encoding="UTF-8") as f: 20 # lists=f.read().split("-") 21 lists=str(json.load(open(file="login.txt",mode="r",encoding="UTF-8"))).split("-")
#写的文件是字符串型,所以json.load()读取出来的也是字符串型的,之所以强转是因为想要变成列表型的,方便读取。 22 if username==lists[0] and password==lists[1]: 23 return True 24 else: 25 print ("登陆失败,请重新登录!") 26 # print(login()) 27 #访问主页面 28 def profile(): 29 # with open(file="login.txt",mode="r",encoding="UTF-8") as f: 30 # lists=f.read().split("-") 31 lists = str(json.load(open(file="login.txt", mode="r", encoding="UTF-8"))).split("-") 32 print("Welcome to {person} page!".format(person=lists[0])) 33 # profile() 34 #主函数 35 def principal(): 36 while True: 37 try: 38 f=int(input("1、注册,2、登陆\n")) 39 if f==1: 40 registered() 41 elif f==2: 42 if login()==True: 43 profile() 44 else: 45 print("Please login again") 46 else: 47 break 48 except:continue 49 if __name__ == '__main__': #作为程序的入口,执行函数,得到最终的结果 50 principal()
运行结果如下:
1、注册,2、登陆 1 What is your name?Lucy Please write your password:17166230 1、注册,2、登陆 2 What is your name?Rose Please write your password:20220621 登陆失败,请重新登录! Please login again 1、注册,2、登陆 2 What is your name?Lucy Please write your password:17166230 Welcome to Lucy page! 1、注册,2、登陆 3 Process finished with exit code 0