1 语言排行榜(2022)
2 python历史
python 弱类型,解释类型语言 最大优势 简洁,短平快
python 数据定义
a="test" b=123
js 语法 后续做web平台也需要掌握的一门语言
var a="test"; var b=123;
java ,c 语法 (强类型语言)
String a=“test"; int b=123;
适合测试,运维人员,金融,大数据分析
python缺陷: Python的执行速度不够快 ,解释器一般c或者java,肯定没有直接用c,java快
不追求规范,Python 2与Python 3不兼容
Python 3.7+和3.6及一下版本有大的区别,加了很多新特性
3 工具介绍
3.1 python解析器
解析器是用来执行Python的代码,通过python -V 检测当前版本 mac 是 python3 -V
解释器是将python语言,翻译成操作系统语言 (语言具有想通性原因)
python os.remove(path) linux rm -rf /a/text java file.delete()
-
解释器有C语言解释器CPython,Java语言解释器Jython,用的最多的是CPython
centos 服务器安装python 需要安装gcc
Linux系统上安装python详细步骤_linux安装python_Dandi0707的博客-CSDN博客
面试常见问题 GIL问题?
-
GIL全称global interpreter lock(全局解释器锁),GIL问题仅存在于CPython解释器中, 即在具有多个CPU的多线程体系结构中,GIL一次只允许一个线程执行,因此GIL已经称为Python的“臭名昭著”的特性,会影响并发性能,python3.7+对这块有优化
全局锁你可以理解多人去卫生间,还没出来之前,别人是不让进去的,就需要上把锁,不过当年设计python时候,只考虑了单cpu,现在多cpu,相当于有多个卫生间,GIL锁的时候把其他卫生间也给锁住了
3.2 第三方库
python 除了自带开发包,有些包是有第三方类库提供,通过pip管理
windows : pip install requests
mac(如果pip有问题) : python3 -m pip install requests
D:\software\python38 Lib (python自带开发包) .... .... site-packages pip install requests (第三方库) requests代码 .... Scripts pip.exe 安装Python第三方模块(包管理器) pip install requests pip3.exe pip3.8.exe python.exe Python解释器
pip和pip3的区别 正在上传…重新上传取消
1、pip是python的包管理工具,pip和pip3版本不同,都位于Scripts\目录下: 2、如果系统中只安装了Python2,那么就只能使用pip。 3、如果系统中只安装了Python3,那么既可以使用pip也可以使用pip3,二者是等价的。 4、如果系统中同时安装了Python2和Python3,则pip默认给Python2用,pip3指定给Python3用。 5、重要:虚拟环境中,若只存在一个python版本,可以认为在用系统中pip和pip3命令都是相同的 6 pip 优化技巧 下载镜像优化 (推荐https) pip install requests -i https://pypi.douban.com/simple/ 豆瓣镜像 pip install requests -i http://pypi.doubanio.com/simple/ --trusted-host pypi.doubanio.com #清华镜像 pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple #全局设置 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
7 批量支持 pip install -r requirements.txt
8 卸载 pip uninstall requests pip list
9 版本问题 pip install requests==2.28.0
10 版本升级 pip install requests --upgrade pip show requests 详细信息查看
3.3 PyCharm
Download PyCharm: Python IDE for Professional Developers by JetBrains
1 外观字体基础设置
2 虚拟环境问题
1 主要解决版本冲突问题
2 勾选global site-packages 系统所有包都会拷贝
正在上传…重新上传取消
3 如果一开始不创建虚拟环境,可以通过python -m venv env 命令创建
不过需要进入Scripts目录 手工激活
正在上传…重新上传取消
权限问题
调整安全策略需要我们打开一个具有管理员权限的 PowerShell ,执行下列命令: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
win10方法:
教你win10的windows powershell怎么打开-纯净之家
可以调整的参数
include-system-site-packages = true #支持拷贝全局开发包
python项目所需 依赖库的备份与还原
在项目根目录 如果有虚拟目录在虚拟目录 pip freeze > requirements.txt用于生成当前项目所依赖的所有依赖库清单 pip download -r requirements.txt -d packages/ 下载所需依赖包到当前路径下的packages/目录下 pip install --no-index --find-links=packages/ -r requirements.txt 离线还原安装项目所需依赖库
3 PyCharm快捷键
【Python入门基础】Pycharm格式化代码常用快捷键_python 格式化快捷键_ZoomToday的博客-CSDN博客
快捷键快捷键记忆正在上传…重新上传取消
能记住操作快捷键
PyCharm快捷键别扭问题 (参考)
ctrl+D 应该是删除 PyCharm是复制
ctrl+x是删除
安装eclipse 插件
选择兼容eclipse
4 代码提示插件安装
AiXcoder 自动代码提示
python模板
【Python学习】如何设置python模板_python代码模板设置_AnastasiaJ的博客-CSDN博客
# -*- coding: utf-8 -*- """ author:码同学 date:${DATE} desc: sample: """
4 基础语法快速复习
基础题考核讲解
4.1 基础类型
什么是数据类型
描述一个人 姓名(张三) 年龄(25) 午餐花费金额(19.5) 希望存款(10个亿)
字符串
name="张三"
数字
age=25
浮点值(变量定义驼峰规则)
lunchFee=19.5
长整数 (变量定义驼峰规则)
hopeDeposit=10000000000000
梦想实现没 boolean
dreamCome=False
数组 list
ARR1 = ["张三", "李四"]
集合set(去重)
ARR2 = {"张三", "李四","李四"}
元组(tuple) 不可更改
ARR3 = ("zhangsan", "李四")
字典(dict) key: value
person ={ "name": "张三", "age": 25, "lunchFee": 19.5, "hopeDeposit": 10000000000000, "dreamCome": True }
4.2 python常见函数
函数和 方法区别
比较常用类型转换
· print() 数据打印 · type() 类型判断 · len() 长度 · int() - 将任何数据类型转换为整数类型 · float() - 将任何数据类型转换为float类型 · ord() - 将字符转换为整数 · hex() - 将整数转换为十六进制 · oct() - 将整数转换为八进制 · tuple() - 此函数用于转换为元组。 · set() - 此函数在转换为set后返回类型。 · list() - 此函数用于将任何数据类型转换为列表类型。 · dict() - 此函数用于将顺序元组(键,值)转换为字典。 · str() - 用于将整数转换为字符串。 · complex(real,imag) - 此函数将实数转换为复数(实数,图像)数 忽略
打印输出
练习题1
string_number = "20" num = int(string_number) # 20 data = string_number * 3 print(data) value = num * 3 # 20 * 3 print(value)
练习题2
print( int("100")*3 ) #300 print( int("123") + int("88") ) #211 print( str(111) + str(222) ) print( int("8") > 7 ) print( str(111) == 111 ) print( bool(-1) ) print( bool(0) ) print( bool("") ) print( bool("你好") ) print( bool("") == bool(0) ) print( True == True) print( True == False)
每个函数的作⽤我都帮你标好了 1. abs # 求绝对值 2. all #Return True if bool(x) is True for all values x in the iterable.If the iterable is empty, return True. 3. any #Return True if bool(x) is True for any x in the iterable.If the iterable is empty, return False. 4. ascii #Return an ASCII-only representation of an object,ascii(“中国”) 返回”‘\u4e2d\u56fd’” 5. bin #返回整数的2进制格式 6. bool # 判断⼀个数据结构是True or False, bool({}) 返回就是False, 因为是空dict 7. bytearray # 把byte变成 bytearray, 可修改的数组 8. bytes # bytes(“中国”,”gbk”) 9. callable # 判断⼀个对象是否可调⽤ 10. chr # 返回⼀个数字对应的ascii字符 , ⽐如chr(90)返回ascii⾥的’Z’ 11. classmethod #⾯向对象时⽤,现在忽略 12. compile #py解释器⾃⼰⽤的东⻄,忽略 13. complex #求复数,⼀般⼈⽤不到 14. copyright #没⽤ 15. credits #没⽤ 16. delattr #⾯向对象时⽤,现在忽略 17. dict #⽣成⼀个空dict 18. dir #返回对象的可调⽤属性 19. divmod #返回除法的商和余数 ,⽐如divmod(4,2),结果(2, 0) 20. enumerate #返回列表的索引和元素,⽐如 d = [“alex”,”jack”],enumerate(d)后,得到(0, ‘alex’) (1, ‘jack’) 21. eval #可以把字符串形式的list,dict,set,tuple,再转换成其原有的数据类型。 22. exec #把字符串格式的代码,进⾏解义并执⾏,⽐如exec(“print(‘hellworld’)”),会解义⾥⾯的字符 串并执⾏ 23. exit #退出程序 24. filter #对list、dict、set、tuple等可迭代对象进⾏过滤, filter(lambda x:x>10, [0,1,23,3,4,4,5,6,67,7])过滤出所有⼤于10的值 25. float #转成浮点 26. format #没⽤ 27. frozenset #把⼀个集合变成不可修改的 28. getattr #⾯向对象时⽤,现在忽略 29. globals #打印全局作⽤域⾥的值 30. hasattr #⾯向对象时⽤,现在忽略 31. hash #hash函数 32. help 33. hex #返回⼀个10进制的16进制表示形式,hex(10) 返回’0xa’ 34. id #查看对象内存地址 35. input 36. int 37. isinstance #判断⼀个数据结构的类型,⽐如判断a是不是fronzenset, isinstance(a,frozenset) 返 回 True or False 38. issubclass #⾯向对象时⽤,现在忽略 39. iter #把⼀个数据结构变成迭代器,讲了迭代器就明⽩了 40. len 41. list 42. locals 43. map # map(lambda x:x**2,[1,2,3,43,45,5,6,]) 输出 [1, 4, 9, 1849, 2025, 25, 36] 44. max # 求最⼤值 45. memoryview # ⼀般⼈不⽤,忽略 46. min # 求最⼩值 47. next # ⽣成器会⽤到,现在忽略 48. object #⾯向对象时⽤,现在忽略 49. oct # 返回10进制数的8进制表示 50. open 51. ord # 返回ascii的字符对应的10进制数 ord(‘a’) 返回97, 52. print 53. property #⾯向对象时⽤,现在忽略 54. quit 55. range 56. repr #没什么⽤ 57. reversed # 可以把⼀个列表反转 58. round #可以把⼩数4舍5⼊成整数 ,round(10.15,1) 得10.2 59. set 60. setattr #⾯向对象时⽤,现在忽略 61. slice # 没⽤ 62. sorted 63. staticmethod #⾯向对象时⽤,现在忽略 64. str 65. sum #求和,a=[1, 4, 9, 1849, 2025, 25, 36],sum(a) 得3949 66. super #⾯向对象时⽤,现在忽略 67. tuple 68. type 69. vars #返回⼀个对象的属性,⾯向对象时就明⽩了 70. zip #可以把2个或多个列表拼成⼀个, a=[1, 4, 9, 1849, 2025, 25, 36],b = [“a”,”b”,”c”,”d”], list(zip(a,b)) #得结果 [(1, 'a'), (4, 'b'), (9, 'c'), (1849, 'd')]
4.3 变量命令规范
三大原则:
-
变量名中只能包含:字母、数字、下划线
-
数字不能开头
练习题 选出变量定义错误的定义
name = "吉诺比利" name0 = "帕克" name_1 = "邓肯" _coach = "波波维奇" _ = "卡哇伊" 1_year = "1990" #错误 year_1_ = "1990" _1_year = "1990" nba-team = "马刺" #- new*name = "伦纳德" #* pass = 99 #关键词
keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
keyword.iskeyword('and')
4.4.循环语句
-
while循环
-
for循环
4.4.1 while循环
while 条件: print(123)
练习题:
-
控制台模拟猜数字,比如66 一直猜直到正确为止
#number = 66 import random number = random.randrange(1,100) print(number) status = True while status: str_num = input("请输入数字:") num = int(str_num) if num == number: print("猜对了") status = False while True: str_num = input("请输入数字:") num = int(str_num) if num == number: print("猜对了") break
-
用户登录 用户 root 密码root ,只能重试3次
counter = 0 while counter < 3: user = input("输入用户名>>>") pwd = input("输入用密码>>>") if user == "root" and pwd == "root": print("登录成功") break else: print("登录失败,请重试") counter = counter + 1
4.4.2 for循环
data_list = ["李泉","王毅","mtx"] for item in data_list: print(item) # 结果 李泉 王毅 mtx
另外一类for循环 + range结合使用。
v1 = range(5) # [0,1,2,3,4] v2 = range(1,5) # [1,2,3,4]
for item in range(5): # [0,1,2,3,4] pass
for item in range(0,5,2): # [0,2,4] pass
for ele in range(0, 10): print(ele, end="_") print() for ele in range(10, 0, -1): print(ele, end="_")
for循环也支持continue和break
for item in range(10): # [0,1,2..9] print(item) break
for item in range(10): # [0,1,2..9] print(1) continue print(item)
5 常见数据类型详解及练习
5.1 字符串
5.1.1 定义
"hello python" 'hello python' """hello python""" #支持换行 '''hello python''' #支持换行
5.1.2 独有功能
1.格式化 三种方式
age =20 name ="zangsan"; print('Happy %d birthday %s!'%(age, name)) print('Happy {} birthday {}'.format(age,name)) print(f'Happy {age} birthday{name}') #拼接 最常用 #print("hello"+name+"age"+age) 不支持这种写法
-
判断是否以xx开头
v1 = "中国上海移动" # True/False result = v1.startswith("中国")
-
判断是否以xx结尾
v1 = "中国上海移动" # True/False result = v1.endswith("移动")
-
判断是否是数字
str = "123456" # 字符串只包含数字 print (str.isdigit()) str = "this is string example....wow!!!" print (str.isdigit()) str = "0" print (str.isdigit()) str = "-1" print (str.isdigit())
-
大小写
msg = "Root" data = msg.upper() # ROOT data = msg.lower() # root print("data数据 {}".format(data)) print("msg 数据 {}".format(msg)) print(f"msg数据 {msg},data数据{data}")
-
去除空白
data = "中国移动 " data = " 中国移动" data = " 中国移动 " result = data.rstrip() # 去right右边空格 result = data.lstrip() # 去left空格" result = data.strip() # "前后空格" #对原来变量没有影响
-
替换
data = "中国上海移动" result = data.replace("上海","**") print(f"data ={data},result={result}")
-
切割
line = "199999999,12312,mtx" data = line.split(",") # ["199999999","12312","mtx"] print(data)
-
拼接
data_list = ['199999999', '12312', 'mtx'] result = ",".join(data_list) print(result) # 199999999,12312,mtx
-
字符串和字节
data = "中国移动A" # 字符串 result = data.encode("utf-8") # 字节 new_data = result.decode("utf-8") # "中国移动A"
5.1.3 公共功能
-
计算长度
name = "root" size = len(name) print(size) #4
-
索引
正在上传…重新上传取消
name = 'testfan' print(name[0]) #t print(name[1]) #e print(name[2]) #s #下标也可以写负数 print(name[-1]) #n print(name[-2]) #a
-
切片
即从"起始"位开始,到"结束"位的前一位结束(不包含结束位本身) 当缺省时,默认起始或者结尾
name = "testfan" print(name[2:5]) # 2到5字符串 stf print(name[:5]) # 不写起始,则认为是从0始 testf #负数是从左到右 定位坐标,取值还是从左到右 print(name[-5:-1]) # 倒叙截取,从-5个字符(重点) stfa print(name[-5:]) #stfan print(name[:-1]) #testfa #第三位是步长,缺省时候是1 #在step>0时,参数1一定小于参数2(左边的下标一定小于右边)数据从右到左; #而在step<0时,参数1一定大于参数2 数据从左到右 print(name[2:5:1]) # 下标2到5,步长是1 print(name[2:5:2]) # 步长为2就后面元素的索引 步长 sf print(name[-2:-5:-1]) # 步长为-1 切片 print(name[::-1]) #数据反转 面试题
-
for循环
name = "testfan" for item in name: print(item, end="") #testfan #反转算法2 str1 = "testfan" a=len(str1) str2 = '' for i in range(a): x = str1[a - 1 - i] str2 += x print(str2) #print(list(range(10))) #print(list(range(len(name))))
5.2 列表list
5.2.1 定义
data = [ 1, 2, 3, "root","北京",True] nums = [11,22,33,44]
5.2.2 独有功能
-
追加,在原列表的尾部追加一个元素
data = [1, 2, 3, "root","北京",True] data.append("上海") print(data) # [1, 2, 3, "root","北京",True,"上海"]
-
插入,将元素插入到原列表的指定位置
# 0 1 2 3 4 5 data = [1, 2, 3, "root","北京",True] data.insert(0,"上海")
data = [1, 2, 3, "root","北京",True] # data.insert(0,"上海") data.insert(2,"上海") print(data)
-
remove,删除
data_list = ['刁民', 'eric', '极光', 'eric'] data_list.remove("eric") print(data_list) # 想要删除的前提是,他一定在列表中存在。
data_list = ['eric', 'zhangsan', '李四', 'mtx', '王五'] # True/False if "eric" in data_list: data_list.remove("eric") print(data_list)
-
清空列表
data_list = ['极光', 'zhangsan', '李四', 'mtx', '王五'] data_list.clear() print(data_list)
-
排序
data_list = [100, 11, 88, 22, 33, 44, 55] data_list.sort() # 从小到大 print(data_list)
data_list = [100, 11, 88, 22, 33, 44, 55] data_list.sort(reverse=True) # 从大到小 print(data_list)
-
翻转
data_list = ['极光', 'zhangsan', '李四', 'mtx', '王五'] data_list.reverse() print(data_list)
-
数组转字符串
data_list = ['极光', 'zhangsan', '李四', 'mtx', '王五'] result = ";".join(data_list) print(result) # 极光;zhangsan;李四;mtx;王五
字符串反转方式3
name = "testfan" mylist = list(name) mylist.reverse() name2 = "".join(mylist) print(name2) #字符串反转方式4 str4 = ''.join(reverse(name))
python模拟抽奖案例
控制台模拟抽奖
data_list = ['极光', 'zhangsan', '李四', 'mtx', '王五']
5.2.3 公共功能
-
长度
data_list = ['极光', 'zhangsan', '李四', 'mtx', '王五'] size = len(data_list) print(size) # 5
-
索引
data_list = ['极光', 'zhangsan', '李四', 'mtx', '王五'] # 读取 print(data_list[0]) data_list[1] data_list[2] data_list[-1] data_list[-2] # 修改 data_list[1] = "张弛" print(data_list) # ['极光', 'zhangsan', '李四', 'mtx', '王五'] # 删除 del data_list[1] print(data_list) # ['极光', '李四', 'mtx', '王五']
-
切片
data_list = ['极光', 'zhangsan', '李四', 'mtx', '王五'] print(data_list[0:2]) #['极光', 'zhangsan']
-
for循环
data_list = ['极光', 'zhangsan', '李四', 'mtx', '王五'] for item in data_list: print(item)
for i in range(5): # [0,1,2,3,4] print(i)
data_list = ['极光', 'zhangsan', '李四', 'mtx', '王五'] for i in range(len(data_list)): # [0,1,2,] item = data_list[i] print(item)
5.3 集合set, 元组tuple
5.3.1 定义
data1 = [11,22,33,44,44] # 列表 data2 = {11,22,33,44,44} # set data3 = (11,22,33,44,44) # 元组
5.3.2 独有功能
set()
tuple()
5.3.3 公共功能
-
长度
v1 = (11,22,33) size = len(v1) print(size)
-
索引
v1 = (11,22,33) v1[0] v1[1] v1[-1]
-
切片
v1 = (11,22,33) v1[0:2]
-
for循环
v1 = (11,22,33) for item in v1: print(item)
5.4 字典
5.4.1 定义
info = { "k1":123, "name":"极光", "age":18 }
5.4.2 独有功能
-
获取值
info = { "age":18, "status":True, "name":"极光" } # 根据键获取对应的值 v1 = info.get("name") print(v1) # "极光" v2 = info["age"] print(v1) # "极光" # 根据键获取对应的值 v1 = info.get("test") print(v1) # None # 根据键获取对应的值 v1 = info.get("xxxxx",666) print(v1) # 666
-
键/值/键值对
info = { "age":18, "status":True, "name":"极光" } data = info.keys() # ["age","status","name"] data = info.values() # [18,True,"极光"] data = info.items() # [('age', 18), ('status', True), ('name', '极光')])
for item in info.keys(): print(item) for item in info.values(): print(item) for item in info.items(): print(item[0],item[1]) for k,v in info.items(): print(k,v)
5.4.3 公共功能
-
长度
info = { "age":18, "status":True, "name":"极光" } size = len(info) print(size) # 3
-
索引
# 读取 info = { "age":18, "status":True, "name":"极光" } v1 = info.get("age") 。 v2 = info["agexxx"] # 增 info['xxx'] = 888 # 删除 del info["age"] # 修改 info["age"] = 999
5.5 嵌套
测试用例设计(json格式),过滤未开启的测试用例
test = [{'caseName': '测试1', 'order': 2,'开启':'是'}, {'caseName': '测试2', 'order': 1,'开启':'是'}, {'caseName': '测试3', 'order': 4,'开启':'否'},{'caseName': '测试4', 'order': 3,'开启':'是'}]
print(type(test)) for item in test: print(type(item)) if(item["开启"]=="是"): print(item) #list特殊用法 for i in range(len(test)): if(test[i]["开启"]=="是"): for k,v in test[i].items(): print(k,v)
案例2 数据提取
#提取data name test2 = {"code":"1","data":[{"name":"testfan0","pwd":"pwd0"},{"name":"testfan1","pwd":"pwd1"},{"name":"testfan2","pwd":"pwd2"}]} print(type(test2)) print(type(test2["data"])); for item in test2["data"]: print(item)
test2 = {("zhangsan1",20,"男"),("zhangsan2",30,"女"),("zhangsan3",18,"女")} set+元组
for item in test2: for item2 in item: print(item2)
6 函数总结
6.1 Python发送邮件
下面就介绍用python发邮件,然后再由此引出函数编程。邮件提醒是自动化测试必备知识
-
注册邮箱
-
基础配置
-
授权码
-
SMTP服务器: smtp.163.com smtp.qq.com smtp.126.com
-
-
代码发送邮件
#1 导入开发包 import smtplib from email.mime.text import MIMEText from email.utils import formataddr # 2.构建邮件内容 msg = MIMEText("码同学测试。", "html", "utf-8") # 内容 msg["From"] = formataddr(["极光", "testfan2@163.com"]) # 自己名字/自己邮箱 msg['to'] = "279313259@qq.com" # 目标邮箱 msg['Subject'] = "邮件测试" # 主题 # 3.发送邮件 server = smtplib.SMTP_SSL("smtp.163.com") server.login("testfan2@163.com", "MSQOTDVQPMKSRZZS") # 账户/授权码 server.sendmail("testfan2@163.com","279313259@qq.com", msg.as_string()) # 自己邮箱/目标邮箱/内容 server.quit()
需求来了
需求1:发送两份邮件
#1 导入开发包 import smtplib from email.mime.text import MIMEText from email.utils import formataddr # 2.构建邮件内容 msg = MIMEText("码同学测试测试1。", "html", "utf-8") # 内容 msg["From"] = formataddr(["极光", "testfan2@163.com"]) # 自己名字/自己邮箱 msg['to'] = "279313259@qq.com" # 目标邮箱 msg['Subject'] = "邮件测试" # 主题 # 3.发送邮件 server = smtplib.SMTP_SSL("smtp.163.com") server.login("testfan2@163.com", "MSQOTDVQPMKSRZZS") # 账户/授权码 server.sendmail("testfan2@163.com","279313259@qq.com", msg.as_string()) # 自己邮箱/目标邮箱/内容 server.quit() #发送第二份邮件 # 构建邮件内容 msg2 = MIMEText("码同学测试测试2。", "html", "utf-8") # 内容 msg2["From"] = formataddr(["极光", "testfan2@163.com"]) # 自己名字/自己邮箱 msg2['to'] = "279313259@qq.com" # 目标邮箱 msg2['Subject'] = "邮件测试" # 主题 # 发送邮件 server2 = smtplib.SMTP_SSL("smtp.163.com") server2.login("testfan2@163.com", "MSQOTDVQPMKSRZZS") # 账户/授权码 server2.sendmail("testfan2@163.com","279313259@qq.com", msg2.as_string()) # 自己邮箱/目标邮箱/内容 server2.quit()
用函数技巧完善
def send_email(title, to): # 1.构建邮件内容 msg = MIMEText(title, "html", "utf-8") # 内容 msg["From"] = formataddr(["极光", "testfan2@163.com"]) # 自己名字/自己邮箱 msg['to'] = to # 目标邮箱 msg['Subject'] = "邮件测试" # 主题 # 2.发送邮件 server = smtplib.SMTP_SSL("smtp.163.com") server.login("testfan2@163.com", "MSQOTDVQPMKSRZZS") # 账户/授权码 server.sendmail("testfan2@163.com", "279313259@qq.com", msg.as_string()) # 自己邮箱/目标邮箱/内容 server.quit() send_email("邮件测试1", "279313259@qq.com") send_email("邮件测试2", "424662509@qq.com") send_email("邮件测试3", "424662512@qq.com")
6.2 函数参数总结(核心重点)
6.2.1 普通参数
def do_something(a1,a2): print(f"type_a {type(a1)}, type_a2 {type(a2)} a1={a1}, a2={a2}"); do_something(11,22) #普通传参 do_something(a1=33,a2=11) #直接给参数赋值 do_something("zhangsan","李四") #字符串类型 do_something("zhangsan",{"abc","abc"}) #set类型 do_something("zhangsan",["abc","abc"]) #list集合
6.2.2 默认参数
def do_something(a1,a2=10): print(f"type_a {type(a1)}, type_a2 {type(a2)} a1={a1}, a2={a2}"); do_something(11,22) #普通传参 do_something(a1=33,a2=11) #参数赋值 do_something(11) #多一种支持 do_something("zhangsan","李四") #任型类型 do_something("zhangsan",{"abc","abc"}) #任型类型 do_something("zhangsan",["abc","abc"]) #任型类型 #注意:定义时,有默认值的参数必须放在最后。
6.2.2 动态参数
-
*可变参数
def do_something(a1,*args): print(f"type_a {type(a1)}, type_args {type(args)} a1={a1}, a2={args}") do_something(1) do_something(1,11) do_something(9,11,123123) do_something(9,["abc","abc"]) #总结 默认参数不改变传入参数类型,可变参数转换成元组 do_something(9,("abc","abc")) #如果是元组
-
** 关键字参数
def do_something(a1,**kwargs): print(f"type_a {type(a1)}, kwargs {type(kwargs)} a1={a1}, kwargs={kwargs}") do_something(1) do_something(1,2) #出错 do_something(2,x=2) #正确 区别 do_something(a1=2,x=2) do_something(1,v1=1,x=11) **kwargs 关键词参数会转换成字典dict类型 特殊例子 info = { "age":18, "status":True, "name":"极光" } print(type(info)) do_something(1,info) #对错? do_something(1,("abc","abc")) 也不支持
-
*,**
def do_something(*args,**kwargs): print(f"args {type(args)}, kwargs {type(kwargs)} args={args}, kwargs={kwargs}") do_something() do_something(11,22) do_something(k1=11,k2=22) do_something(11,22,k1=11) do_something((11,22),k1=11,k2=22) do_something((11,22),[1,2],k1=11,k2=22)
6.3 返回值
函数本质上是一大堆代码的集合,函数放在一起目的是为了让他帮助我们完成某些事。
def plus(v1,v2): data = v1 + v2 + 100 return data value = plus(50,33) print(value) # 183
关于返回值的三个关键知识点:
-
返回值可以是任意类型,函数没有返回值,默认返回None
def f2(): v1 = 100 v2 = 900 res = f2() # None
#返回list def f1(): return {11,22,3} res = f1() #返回字典 def f2(): return { "age":18, "status":True, "name":"极光" } res = f2() print(res)
-
在函数中一旦遇到return,立即结束函数的执行。
def func(): print(1) for i in range(5): print(i) return 999 print(2) res = func() print(res)
-
在函数返回值时,可能会用逗号分开多个值,会打包成元组
def func(): return 1,2,",mtx" v1 = func() # (1,2,"mtx") print(v1)
6.4 lambda函数
def func(a1,a2): return a1 + a2 v1 = func(1,2) print(v1) # 3
func = lambda a1,a2 : a1 + a2 v2 = func(1,2) print(v2) # 3
编程题,测试用例排序过滤问题
test = [{'caseName': '测试1', 'order': 2,'开启':'是'}, {'caseName': '测试2', 'order': 1,'开启':'是'}, {'caseName': '测试3', 'order': 4,'开启':'否'},{'caseName': '测试4', 'order': 3,'开启':'是'}] #排除未开启测试用例,按照order顺序测试 升序 def takeOrder(elem): return elem["order"] def filterOpen(elem): return elem["开启"] == '是' #过滤未开启测试用例 test =list(filter(filterOpen, test)); #根据order排序 test.sort(key=takeOrder) print(test) #过滤 test=list(filter(lambda elem: elem["开启"]=='是',test)); #排序 test.sort(key=lambda elem:elem['order']); print(test)
6.5 作用域
global关键字
# 全局变量 CITY = "上海" def info(): # 局部变量 name = "root" print(name) # root CITY = "北京" # 局部变量 print(CITY) # 北京 print(CITY) info() print(CITY)
# 全部变量 CITY = "上海" def info(): # 局部变量 name = "root" print(name) # root global CITY CITY = "北京" # 局部变量 print(CITY) # 北京 print(CITY) # 上海 info() print(CITY)
案例练习
get_add_sum(),每次调用该函数都只能传一个数 num ,每次返回的结果都是基于上一次结果的值 sum 进行累加操作。例如,sum的默认值为0,如果我们依次调用 get_add_sum(10)、get_add_sum(20)、get_add_sum(30) 后,期望得到的最终结果是 60
sum = 0 def get_add_sum(num): global sum sum += num return sum print(get_add_sum(10)) # 输出:10 print(get_add_sum(20)) # 输出:30 print(get_add_sum(30)) # 输出:60 print(sum) # 输出:60
6.5 闭包(高频面试题)
当我们在外部函数中定义了一个内部函数,并且内部函数能够读取到外部函数内的变量,这种函数我们就称为闭包。简单来说,闭包就是能够读取外部函数内的变量的函数。本质函数嵌套
sum = 0 def get_add_sum(sum): def add_num(num): nonlocal sum sum += num print(f"add_num {sum}") return sum print(f"get_add_sum {sum}") return add_num add = get_add_sum(10) print(add(10)) # 输出:10 print(add(20)) # 输出:30 print(add(30)) # 输出:60 print(sum) # 输出:0 nonlocal不能改变全局变量
多函数闭包
sum = 0 def get_add_sum(sum): def add_num(num): nonlocal sum sum += num print(f"add_num {sum}") return sum def add_num2(num): nonlocal sum sum += num*2 print(f"add_num2 {sum}") return sum print(f"get_add_sum {sum}") return add_num2 add = get_add_sum(sum) print(add(10)) # 输出:20 print(add(20)) # 输出:60 print(add(30)) # 输出:120 print(sum) # 输出:0 nonlocal不能改变全局变量
6.7 装饰器
pytest 顺序执行,重复执行,失败重试
https://www.cnblogs.com/keenajiao/p/16528991.html
所谓[装饰器],就是在不改变一个函数内部代码的前提下,给函数额外增加功能的东西。装饰器本质就是一个嵌套函数和闭包的应用, 由于框架已经提供了简单应用,现在面试就会问更深入原理内容
def outer(func): def inner(): print("执行前新增业务") res = func() # 被装饰器的原函数 print("执行后新增业务") return res return inner @outer def info():
装饰器内获取函数参数
def outer(func): def inner(*args,**kwargs): print(f"执行前新增业务{args},{kwargs}") res = func(*args,**kwargs) # 被装饰器的原函数 print("执行后新增业务") return res return inner @outer def info(a): print(f"原来的info函数{a}") if __name__ == '__main__': info(1);
装饰器参数+函数参数同时获取实现
@get_parameter(1,2) def info(a): print(f"原来的info函数{a}")
def get_parameter(*args,**kwargs): #装饰器传参数 def log_time(func): print(f"get_parameter{args}, {kwargs}"); def make_decorater(*args,**kwargs): print(f"make_decorater{args}, {kwargs}"); print('现在开始装饰') func(*args,**kwargs) print('现在结束装饰') return make_decorater return log_time
7 文件读写
参考文件读写pdf
8 异常体系
参考异常pdf
异常就是运行期检测到的错误。计算机语言针对可能出现的错误定义了异常类型,某种错误引发对应的异常时,异常处理程序将被启动,从而恢复程序的正常运行。
-
BaseException:所有异常的 基类
-
Exception:常规异常的 基类
-
StandardError:所有的内建标准异常的基类
-
ArithmeticError:所有数值计算异常的基类
-
FloatingPointError:浮点计算异常
-
OverflowError:数值运算超出最大限制
-
ZeroDivisionError:除数为零
-
AssertionError:断言语句(assert)失败
-
AttributeError:尝试访问未知的对象属性
-
EOFError:没有内建输入,到达EOF标记
-
EnvironmentError:操作系统异常的基类
-
IOError:输入/输出操作失败
-
OSError:操作系统产生的异常(例如打开一个不存在的文件)
-
WindowsError:系统调用失败
-
ImportError:导入模块失败的时候
-
KeyboardInterrupt:用户中断执行
-
LookupError:无效数据查询的基类
-
IndexError:索引超出序列的范围
-
KeyError:字典中查找一个不存在的关键字
-
MemoryError:内存溢出(可通过删除对象释放内存)
-
NameError:尝试访问一个不存在的变量
-
UnboundLocalError:访问未初始化的本地变量
-
ReferenceError:弱引用试图访问已经垃圾回收了的对象
-
RuntimeError:一般的运行时异常
-
NotImplementedError:尚未实现的方法
-
SyntaxError:语法错误导致的异常
-
IndentationError:缩进错误导致的异常
-
TabError:Tab和空格混用
-
SystemError:一般的解释器系统异常
-
TypeError:不同类型间的无效操作
-
ValueError:传入无效的参数
-
UnicodeError:Unicode相关的异常
-
UnicodeDecodeError:Unicode解码时的异常
-
UnicodeEncodeError:Unicode编码错误导致的异常
-
UnicodeTranslateError:Unicode转换错误导致的异常
异常体系内部有层次关系,Python异常体系中的部分关系如下所示: