python接口测试自动化之python基础语法
一、pycharm的使用和python基本语法
(一)、pycharm的使用和python环境
1、python以及pycharm的安装
- python 的版本选择:3.x 版本,不要安装2.x 版本,有很多语法不一样
- 如何确定自己 python 版本: cmd: python
- 不是内部命令:python没有正确安装,原因大概率是因为没有配置环境变量(配置环境变量后重启电脑生效)
- 指定 python 的安装目录:一般来说是安装在 d:\python37
- 测试python是否安装成功
- cmd: python
- cmd: pip ,或者 pip3 , 有任何一个出现命令不存在,
- 额外注意:loadrunner 中也有pip,这个pip配置环境变量了之后,python中的pip也需要配置环境变量
- prcharm 的版本选择:社区版够用
- pycharm 只是一个工具,python 才是关键
2、pycharm 新建项目
- 新建项目
- file ---> New Project
- 退出项目
- file ---> Close Project
- 切换项目
- file ---> Open
- file ---> Open Recent
3、文件、目录、包的创建和管理
- Project ---> 右键 ,可以新建文件、目录和包
4、pycharm 的基础使用
- python 代码是保存到以 .py 结尾的文件当中
- .py 文件又是放到各个文件夹(目录)下面的
5、如何运行代码:
- 右键,点击 run
- 命令行运行:点击底下的 Terminal
- 进入项目路径
- python 拼接好的路径/python文件.py
6、安装第三方库
第三方库:是别人已经写好的 python 代码
第一种方法:
- 安装:pip install 库名
- 卸载:pip uninstall 库名
第二种方法:pycharm :不要勾选 user's site package
第三种方法:库放在国外的服务器上,需要用到国内安装源,python国内源
- pip install 库名 -i 源地址
- pip install openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple
python国内源:
清华:https://pypi.tuna.tsinghua.edu.cn/simple
阿里云:http://mirrors.aliyun.com/pypi/simple/
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
华中理工大学:http://pypi.hustunique.com/
山东理工大学:http://pypi.sdutlinux.org/
豆瓣:http://pypi.douban.com/simple/
(二)、python基本语法
1、基本语法
print 输出
- 表示在屏幕上打印出(显示出)
- 使用的任何的代码,双引号是半角,英文
- print 默认输出是换行的,不同的数据之间用逗号隔开
python注释: 表示在 python 当中不会运行的文字(不会当成代码), 是说明下面的代码是什么?
- # 表示单行注释 , Ctrl + /
- """ """ 表示多行注释
- ''' ''' 表示多行注释
缩进:
- 现在这个阶段,所有的代码全部顶格写,不要进行缩进。
数值
- 和数学中的数值表示是一样的(注意点:数值不用加引号)
字符串
- python 使用引号来表示字符串(一串文字)
变量
- 什么是变量:是用来存储数据
- a = 100
- b = 200
- c = “ hello world”
- 变量名的命名规范:
- 只能包含数字、字母、下划线,
- 不能以数字开头,
- 不能有关键字( 注意点 )
- python 中所有的关键字: keyword.kwlist
- 尽量做到见名知意
- 尽量不要用拼音
- 什么是变量:是用来存储数据
标识符:(凡是我们自己取的名字,都是标识符。)
- 规范:标识符由字母、数字、下划线组成,不能使用关键字
- 标识符包括:变量名、函数名、类名、模块名、项目名
- 在python中,所有标识符可以包括英文,数字以及下划线(_),但不能以数字开头。
- python 中的标识符是区分大小写的,大写的 A 和小写的 a 不一样
标识符的命名风格:
- 下划线命名法:
- 规范:单词字母小写,单词之间使用下划线连接
- 如:max_number ,test_data
- 大驼峰命名法:
- 规范:每个单词的第一个字母大写
- 如:MaxNumber , TestData
- 小驼峰命名法:
- 规范:第一个单词以小写字母开始,第二个单词的首字母大写
- 如:maxNumber , testData
- 下划线命名法:
input 用户输入
- 从控制台里面获取一个数据,获取到的类型是字符串类型
二、python中常见数据类型
(一)、数值类型 & 运算符
1、数值类型数据
- 数值类型
- 整数(int):整数
- 浮点数(float):小数
- 布尔值(bool):只有两个值 True 和 False
2、python 常见运算符
算术运算符:
- +
- -
- *
- /
- 除法运算一定要注意:除数不能为0
- 除数如果为0,就会报错:ZeroDivisionError: division by zero
- //
- 整除
- %
- 余数:模运算
# +
print(5 + 6)
# -
print(7 - 8)
# *
print(2 * 3)
# /
# 只要是进行除法运算,得到的是一个 float
print(4 / 3)
print(4 / 2) # 除法运算一定要注意,除数不能为 0
# 除数如果为0,就会报错:ZeroDivisionError: division by zero
# 程序报错以后,就无法继续运行
# print(2/0)
# print('hello world') # // 得到的是一个整数。 整除
print(4 // 3) # % 取余数 : 模运算
print(4 % 3) # ** 幂运算 4的3次方
print(4 ** 3)
赋值运算符
- =
- +=
- -=
- *=
- /=
- //=
- %=
- **=
name = 'yuze'
age = 18 #涨一岁
age = age + 1
print(age) #缩写 age += 1 ==> age = age + 1
age += 2
print(age) age /= 3
print(age)
比较运算符: 比较运算得到的结果是一个 bool 值, True 或 False
- <
- >
- <=
- >=
- !=
> 大于
print(5 > 4) # True < 小于
print(6 < 3) # False >= 大于等于
print(6 >= 3) # True <= 小于等于
print(6 <= 3) # False != 不等于
print(6 != 3) # True TODO: == 才是比较运算, 一个 = 是赋值运算
print(6 == 6)
逻辑运算 : 可以使用()提高优先级
- and
- or
- not
a = 3 > 4
print(a) b = 4 != 5
print(b) # 运算 and
# 每一个都为 True print(a and b) # False # 运算 or
# 只要有一个为 True print(a or b) # True # 练习 a = True
b = 5 == 4 # False
c = 5 != 3 # True print(a and b or c) # True
print(a or b and c) # True # python 的运算有没有优先级,如何设置优先级
# 使用 () 设置优先级
print(((a and b) or c) and b) # not 取反
print(not(b)) # True
身份运算
- is
- is not
成员运算
- in
- not in
# in name = 'yuz' print('u' in name) # True
print('uz' in name) # True
print('uai' in name) # False # TODO: in 一定是连着的, yz 是一个整体
print('yz' in name) # False
print('Y' in name) # False
3、随机数模块: random (python 官方库)
随机生成 0-1 之间的浮点数:random.random()
随机生成 0-100 之间的浮点数:random.randint(1, 100)
import random
f_num = random.random() print(f_num) num = random.randint(0, 100) print(num)
(二)、字符串
本节问题:
问题一:python中如何表示字母,比如要将一个人的名字储存下来?
问题二:字符串如何定义?
问题三:字符串如果要换行怎么办?
问题四:数值类型的数据可以转换成字符串吗?
问题五:可以把两个字符串组成一个吗?
问题六;如何获取字符串中某个具体的字符?
1、字符串的定义:
单引号、双引号:定义单行字符串
三引号、三双引号: 多行字符串定义
空字符串: s=''
str():
注意点:字符串中有单引号时,外面用双引号注意区分
"""字符串的定义 如何表示字符串:
- 引号表示字符串
- 单引号 ''
- 双引号 ""
- 三引号 ''' '''
- 三双引号 """ """
""" name1 = "yuze" print(name1) name2 = 'yuze' print(name2) name3 = '''yuze''' print(name3) name4 = """yuze""" print(name4) print(name1 == name2 == name3 == name4) # True print(name1 == name2) # True print(name1 == name3) # True print(name1 == name4) # True
2、字符串的切片和下标取值
1、下标索引取值
- 下标取值:可以正向取,也可以反向取
- 注意点:正向从 0 开始,反向从 -1 开始
name = 'yuzwang' print(name[1]) # u print(name[0]) # y # 获取第3个字符 print(name[2]) # z # 获取 g print(name[6]) print(name[-1])
2、切片: [:][::]
- 问题:下标取值只能获取单个元素,现有字符串 str1='hello python' ,如果要获取出来 python 应该怎么做?
- 切片的语法: 和下标取值一样使用中括号进行切片,有两种用法:
- [a:b] :a代表起始位置下标, b 代表终止位置下标(左闭右开);
- [a: b: c] : a代表起始位置下标, b 代表终止位置下标(左闭右开),c 代表步长。
"""字符串的切片 slice 获取多个字符 索引获取的公式: m_str[start:end:step] 注意:end - start 的符号 必须和 step 的符号相同才可以获取到索引 step 的值不能为0 """ name = 'yuzwang' # 要 1 和 2
print(name[1:2]) # u
print(name[0:1]) # y # TODO: 这个才是对的
# TODO: 顾头不顾腚,取头不取尾,取左不取右
print(name[0:2]) # yu
print(name[3:6]) # wan # 什么是 step , 取完第一个索引,把索引 + 多少
# step = 2
print(name[3:6:2]) # wn
print(name[1:5:3]) # ua # step 可以为负数
print(name[5:1:-3]) # nz
print(name[5:1:3]) # 取不到值 None
print(name[1:4:-2]) # 取不到值 None # TODO: end - start 的符号 必须和 step 的符号相同才可以获取到索引
# TODO:step 的值不能为0,否则会报错:ValueError: slice step cannot be zero
print(name[1:5:0]) # TODO: IndexError
print(name[1000000]) # IndexError: string index out of range
print(name[1:1000000]) # uzwang 不会报错,会取到所有值 name = "yuzewang" # 省略 end ,表示取到最后
print(name[1:]) # 省略 start ,表示从 0 开始
print(name[:5]) # 复制,copy 从头到尾,
# TODO: 面试题:复制字符串
print(name[:])
name_copy = name[:]
print(name_copy) # 倒序 '123456' ==> '654321'
# TODO:面试题:倒序一个字符串
print(name[::-1]) # gnawezuy
3、字符串拼接和转义
+ 号:'hello' + 'python'
字符串转义:
- \n: 换行符
- \t: 水平制表符
- 关闭转义:r'hello \n python'
name = 'yuz'
family_name = 'wang' print(name + family_name) print(name + ' ' + family_name) 字符串和数字能不能相加 print('yuz' + 7) # 字符串和数字不能直接相加,会报错:TypeError: must be str, not int print('yuz' + str(7)) # yuz7 数据类型的转化 print(int(name)) # 报错:ValueError: invalid literal for int() with base 10: 'yuz' print(int('12')) # 12 print(bool(34)) # True bool 转化,只要是非0,非空的就是True 字符串换行 '\' 不会分开成两行 name = "yuze ooasfjojo" \ "wefwllfjlj" print(name) # yuze ooasfjojowefwllfjlj # 三引号换行,得到多行数据 name = """yuze flaljlkfjlajl lsajllakj fjk sjljjfljladf aljfl """ print(name) # 单引号中 \n 表示换行 name = 'kaixina lajj\nlfljajljssfjdlk\njljajs' print(name)
4、字符串常用方法
- join : 字符串拼接
name = "qin er cai"
# 字符串拼接
print(name + 'wang')
# 使用 join 拼接
print(name.join(['a','b','c'])) # aqin er caibqin er caic
# 时间 ['2020', '08', '03'] 用 / 连接起来
print('/'.join(['2020', '08', '03'])) # 2020/08/03
print('2020' + '/' + '08' + '/' + '03') # 2020/08/03
- find : 查找元素的位置
# find:在字符串当中查找某个字符或者字符串的位置
# 会得到索引
a = "wangyuze is coming"
print(a.find('e')) # 7
index = a.find('e')
print(index) # 7
# 如果找的有两个呢? i,会得到第一个
print(a.find('i')) # 9
# 如果是一个子串呢? ng
print(a.find('ng')) # 2
# 如果找不到怎么办?会得到 -1 ,这是规定
print(a.find('isnot')) # -1
# 如果子串不在一起,也是找不到,返回 -1
print(a.find('wn')) # -1
# index 约等于 find
# 区别:index 找不到元素的时候,会报错,find 找不到的时候返回-1
print(a.index('ng')) # 2
print(a.index('wn')) # ValueError: substring not found
- count : 查找元素的个数
# count 统计某个字符出现的次数
m_str = 'foweofpweef'
print(m_str.count('o')) # 2
song = "我爱你,我喜欢你,我..."
print(song.count('我')) # 3
- replace : 替换字符
# replace 替换
song = "我爱你,我喜欢你,我..."
print(song.replace('你', 'ta')) # 我爱ta,我喜欢ta,我...
- split : 字符串分割
# split 切分、切割 ==》 和 join 相反
time_string = '2020/08/03'
print(time_string.split('/')) # ['2020', '08', '03']
format : 格式化输出
upper : 将字母大写
# upper 所有字母都大写
name = 'yuze'
print(name.upper()) # YUZE
- lower : 将字母小写
# lower 所有字母都小写
name = 'JECK'
print(name.lower()) # jeck
- strip : 去掉两边的特殊字符,如果什么都不传,就是去掉空格或者换行符
# strip 去掉两边的特殊字符,如果什么都不传,就是去掉空格或者换行符
name = ' yuze wang '
print(name.strip()) # yuze wang
print(name)
cp = "&雨泽&哈哈&"
print(cp.strip('&')) # 雨泽&哈哈
- len : 计算字符串长度
# len 计算字符串的长度
name = 'yuzewang '
print(len(name)) # 9
5、字符串格式化输出
format 格式化输出
- format() 功能强大,该函数把字符串当成一个模板,通过传入的参数进行格式化,并且使用 {} 作为特殊字符代替 %
数据 格式 结果 描述 5.11111 {:.2f} 5.11 保留小数点后两位 0.25 {:.2%} 25.00% 百分比格式 aa {:<10} aa 左对齐(宽度为10) aa {:^10} aa 中间对齐(宽度为10) - format 字符串的格式化
```
# 现在需要打印下面的格式:
-------------------
借条
借款人:yuz
债权人:double king
金额:500
------------------- loan_name = 'yuz'
rich_man = 'double king'
money = 500 # # 方法一:
# print("---------------------")
# print('借条')
# print('借款人:' + loan_name)
# print('债权人:' + rich_man)
# print('金额:' + str(money))
# print('---------------------')
#
# # 方法二:
# {} 表示占坑符,占位符
# 位置一定要匹配,不能乱填顺序
# print("""
# -------------------
# 借条
# 借款人:{}
# 债权人:{}
# 金额:{:.2f} 万
# -------------------
# """.format(loan_name, rich_man, money))
#
#
# # 方法三:
# # f-string : python3.6 以后才支持
# print(f"""
# -------------------
# 借条
# 借款人:{loan_name}
# 债权人:{rich_man}
# 金额:{money} 万
# -------------------
# """)传统的格式化输出 %
符号 描述 %s 格式化字符串 %d 格式化整数 %f 格式化浮点数字,可指定小数点后的精度
(三)、列表和元组
1、列表
列表的定义
- 是一种数据类型,可以用来存储多个数据
- 列表用 [ ] 来标识
- 列表内部的元素可以是任意类型的
- 列表是使用最频繁的数据类型之一
列表的常见操作
下标取值(索引取值):获取某一个元素
切片操作:获取多个元素
- 有步长的切片过程:先根据起始位置和终止位置,将内容切出来,然后再根据步长分为若干部分,然后将每部分的第一个元素拿出来,得出结果。
修改元素的值:可以通过下标修改指定位置的元素。
# 5 个人,5个大佬 , 使用列表
big_boss = ['Demons', 'Go', 'EE', '上善若水', 'summer']
print(big_boss) # 元素可以是任意的数据类型
big_boss = ['Demons', 11, True, 33.33, 'summer']
print(big_boss) big_boss = ['Demons', 11, True, 33.33, ['a','b','c']]
print(big_boss) big_boss = ['Demons', 11, True, 33.33, ['a','b',['yuz',True]]]
print(big_boss) # 索引: 获取索引为 0 的元素
print(big_boss[0]) # Demons
print(big_boss[-1]) # ['a', 'b', ['yuz', True]]
print(big_boss[-2]) # 33.33
print(big_boss[2]) # True # 获取 a
print(big_boss[-1][0]) # a
last_one = big_boss[-1]
print(last_one[0]) # a # 获取 'yuz'
print(big_boss[-1][-1][0]) # yuz # 切片
print(big_boss[:3]) # ['Demons', 11, True]
列表嵌套
列表中如果有多层嵌套,取值时需要一层一层的取值
lst = [
'a',
'b',
[1,2,3]
] print(lst[0]) # a print(lst[-1][1]) # 2
列表的方法
- 增:append 、insert 、 extend
- 删:pop 、 remove
- 改:通过下标修改值
- 查:index 、 count
- 其他:reverse 、 sort
方法 描述 append 在列表的尾部加入一个元素 insert 在指定位置插入一个元素 extend 插入多个元素 pop 删除一个元素(默认从列表尾部删除,也可以指定下标进行删除) remove 删除指定的元素(从前往后找) index 查找元素的位置,找到第一个就返回结果 count 统计元素的个数 sort 将列表的元素进行排序 reverse 将列表内元素反序(头变为尾,尾变头) # TODO:坑
dalaos = ['随风'] new_dalao = dalaos.append('利己')
print(dalaos) # ['随风', '利己'] # append() 返回 None
print(new_dalao) # None # 再添加多个,['一罐','本本','可爱','美雪'] 添加到最后
dalaos.extend(['一罐','本本','可爱','美雪'])
print(dalaos) # TODO: 坑2 报错:AttributeError: 'NoneType' object has no attribute 'append'
new_dalao = dalaos.append('sfo').append('hello').append('sof')
print(new_dalao) # 增加某个元素,修改的是原来的变量 lst
lst = ['yuz', 'shanshan', 'rita']
lst.append('裴纶')
print(lst) # ['yuz', 'shanshan', 'rita', '裴纶'] # insert 指定索引位置添加元素,不是获取索引,不用[]
lst.insert(1, '仙人球')
print(lst) # ['yuz', '仙人球', 'shanshan', 'rita', '裴纶'] # extend 添加多个,可以合并 2 个列表
lst.extend(['tiger', 'f2'])
print(lst) # ['yuz', '仙人球', 'shanshan', 'rita', '裴纶', 'tiger', 'f2'] lst = [1,2,3]
lst.append(3)
print(f"第一次尝试{lst}") # 第一次尝试[1, 2, 3, 3]
# lst.extend(3)
# print(f"第二次尝试{lst}") # 报错:TypeError: 'int' object is not iterable
lst.extend([3])
print(f"第三次尝试{lst}") # 第三次尝试[1, 2, 3, 3, 3] a = [1,2,3]
b = [4,5,6] # b 是作为一个整体,一个元素,添加到 a 当中
# a.append(b)
# print(a) # [1, 2, 3, [4, 5, 6]] # b 是拆开里面元素,作为多个元素,添加到 a 当中
a.extend(b)
print(a) # [1, 2, 3, 4, 5, 6]
"""列表的删除
- remove
- delete
- pop """ # remove: 在列表当中删除指定的值
big_boss = ['糖', '木易', '均价']
big_boss.remove('木易')
print(big_boss) # ['糖', '均价'] # delete 异类:尽量不要用
# del big_boss[0]
# print(big_boss) # ['均价'] # pop 0 代表索引为 0
big_boss.pop(0)
print(big_boss) # ['均价'] # 获取索引为 0 的值
print(big_boss[0]) big_boss.append('木易')
print(big_boss) # ['均价', '木易']
"""列表的修改 lst[0] = 1
""" lst = [1,2,3] lst[1] = 'a'
print(lst) # [1, 'a', 3] lst[1],lst[2] = 'c', 'd'
print(lst) # [1, 'c', 'd'] lst[1:] = 5,6
print(lst) # [1, 5, 6]
"""列表的方法
- index
- count
- sort
- reverse
- clear """ lst = [4,5,6,5] # # 统计
# print(lst.count(5)) # 2
#
# # index 查找得到第一次出现的索引值
# print(lst.index(5)) # 1
#
# # sort 排序
# print(lst.sort()) # None
#
# lst.sort()
# print(lst) # [4, 5, 5, 6]
#
#
# # reverse 反向,倒序 , 相当于 [::-1]
# lst.reverse()
# print(lst) # [6, 5, 5, 4] # 反向排序
lst.sort(reverse=True)
print(lst) # [6, 5, 5, 4] # clera 清除一个列表
lst.clear()
print(lst) # []
2、元组
元组的定义:
- 元组定义在小括号中,元组内部的数据:它支持数字,字符串甚至可以包含元组(即嵌套)
元组的常见操作
- 下标取值:元组内部的数据是有序的,可以通过下标获取对应的元素
注意点
- t = () 空元组
- t = (1,) 只有一个数据的时候要注意加逗号
- 元组的值不可以修改,是属于不可变数据
元组的方法
- count : 查找元素的个数
- index :查找元素下标
tuple_yuz = ('yuz','一罐',['闲人','七七','小骄傲'])
# 修改的是元组的元素,元组的元素是列表
# tuple_yuz[2] = ['新列表']
# print(tuple_yuz) # 不能修改元组的元素 # 为什么这里可以改??
# 元组的不可变是相对的,不是说里面所有的内容都完全不能变
# 只要看索引的前面是不是一个可变的类型
tuple_yuz[2][0] = ['新列表']
print(tuple_yuz) tuple_yuz = ('yuz','一罐',{'tuple':'yuze'})
# 索引前面是元组,代表我们要修改的是元组的元素,不可以
# tuple_yuz[2] = 'hello world' # tuple_yuz[2] 是字典,可变类型,可以直接修改
tuple_yuz[2]['name'] = 'hello world'
print(tuple_yuz) # 索引前yuz是列表,可以改变
yuz = ['yuz','一罐',('四叶草','晓峰')]
yuz[2] = 'hello'
print(yuz) # yuz[2]是元组,不可变
yuz[2][1] = 'youxi'
tuple_demo = ()
print(tuple_demo) # TODO:坑 ,一个元素的元组表示,不是一个元组,而是去掉括号后的原始数据类型
# tuple_demo_2 = (1)
# print(tuple_demo_2) # 如果想表示一个元素的元组,记得务必在元素后面加一个逗号
# tuple_demo_3 = (1,)
# print(len(tuple_demo_3)) tuple_demo_4 = (1,3,4,5,5,)
print(len(tuple_demo_4))
tuple_demo_5 = 1
print(tuple_demo_5) # 元组解包
family_name,name = ('wang','yuze')
# family_name,name = ('wang','yuze','hello') # 值要一一对应,否则会报错
print(family_name)
print(name) a,b = 3,4
print(a)
print(b) family_name,name,*other = ('wang','yuze','hello','world')
print(family_name)
print(name)
print(*other)
3、字符串、列表、元组总结
- 序列类型:
- 字符串、列表、元组,统称为序列类型数据(内部的元素是有顺序的)
- 通用操作:
- 下标取值:
- 切片:
- 获取元素总数: len()
(四)、字典和集合
- 问题:
- 使用一个列表存储了一个学生信息,姓名,年龄,电话号码,stu = ['小明', '18', '13812341234']
- 问题一:当前如果电话号码写错了,怎么修改
- 问题二:当前列表中有10个设置100个元素,不知道电话号码具体的下标,怎么修改电话号码
1、字典
字典的定义:
也是用来存储多个数据的
字典:字典用 {} 来标识
字典能够表示元素更具体的意思,每个元素表示的意义是什么,可以通过 key 命名
字典的结构:就是将它看做是一个 {key:value} 键:值 对的集合,键必须是唯一的(在一个字典中)
空字典 : {}
字典定义的方式:
# 方式一:
dic = {'name':'musen', 'age':18} # 方式二:
dic = {name = 'musen', age = 18}
注意点:
- 字典中的键必须是唯一的
- key 不能出现重名,在一个字典当中,key 之间是不一样的
- key 不能变的,列表是不能作为 key 的
- 可变类型数据:字典定义后可以修改内部元素
- 注意点:字典的键必须是不可变类型的(一般情况下都是字符串),值可以是任意类型的数据(字典,元组,列表等等都可以)
字典的增删改查
增
通过指定键去添加相应的值
dic[key] = valueupdate() : 将一个字典的所有元素更新到另一个字典中
# 简单理解
dic.update({'a':1, 'b':2})改:通过指定键去修改对应的值
dic[key] = value删
pop() : 删除指定的键,删除的键不存在会报错(避免错误可以添加默认值)
dic.pop(key)popitem() : 删除一个键值对,删除最后一个添加的元素
- 之前版本是随机删除一个元素,python3.7新特性,删除最后添加的元素
关键字 del : 通过键删除
del dic[key]
查
- get() : 获取键对应的值
- keys() : 获取所有的键,可以用 list 将结果转换成列表
- values() : 获取所有的值,可以用 list 将结果转换成列表
- items() : 获取所有的键值对,可以用 list 将结果转换成列表,列表中每个键值对组成一个元组。
# 列表:当每个元素有具体的意义,你又想去单独获取的时候,可读性不强
beisheng = ['星际穿越', '蜘蛛侠', '上海堡垒', '分手大师', '前任3']
print(beisheng[2]) # 字典:key: 元素的名称, value: 元素的值 , 键值对:成对
# 用 {} 在最外面
# key: value, key1: value1
beisheng = {'favor':'星际穿越','hate':'蜘蛛侠','first':'上海堡垒','last':'分手大师','twice':'前任3'} print(beisheng['hate']) # 蜘蛛侠 # 重名的key
beisheng = {'favor':'星际穿越',
'hate':'蜘蛛侠',
'first':'上海堡垒',
'favor':'分手大师',
'twice':'前任3'}
# favor 后面的值会覆盖前面的值
print(beisheng['favor']) # 分手大师 print(beisheng) # {'favor': '分手大师', 'hate': '蜘蛛侠', 'first': '上海堡垒', 'twice': '前任3'} # key 不能是列表
# beisheng = {'favor':'星际穿越',
# ['hate']:'蜘蛛侠',
# 'first':'上海堡垒',
# 'favor':'分手大师',
# 'twice':'前任3'}
# print(beisheng) # 报错:TypeError: unhashable type: 'list' # 键为数字: 没有意义,不建议使用
beisheng = {1:'星际穿越',
3:'蜘蛛侠',
2:'上海堡垒',
5:'分手大师',
4:'前任3'}
print(beisheng) # {1: '星际穿越', 3: '蜘蛛侠', 2: '上海堡垒', 5: '分手大师', 4: '前任3'}
beisheng = {'favor':'星际穿越',
'hate':'蜘蛛侠',
'first':'上海堡垒',
'last':'分手大师',
'twice':'前任3'} # 获取,查
print(beisheng['hate'])
# 字典没有索引和切片 # 修改
beisheng['hate'] = '蝙蝠侠'
print(beisheng) # {'favor': '星际穿越', 'hate': '蝙蝠侠', 'first': '上海堡垒', 'last': '分手大师', 'twice': '前任3'} # 添加, 和修改是一样的
# 什么时候是修改,什么时候又是添加?
# 看 key:当 key 已经存在的时候,是修改,当之前没有这个key,就是添加。
beisheng['scared'] = '贞子'
print(beisheng) beisheng['scared'] = '午夜凶铃'
print(beisheng)
2、集合
定义:
- 集合中的元素不能重复
- 花括号 或 set() 函数可以用来创建集合
注意:
- 要创建一个空集合你只能用 set() 而不能用 {} ,因为后者是创建一个空字典
集合的方法:
- 增加元素 : add
- 删除元素 :pop , remove
- 自动化测试中很少用集合来存放数据,更多内容请自行扩展
集合的重要应用场景:去重
集合的交集、并集、差集
- a & b : 集合 a 和 b 中都包含了的元素
- a | b : 集合 a 或 b 中包含的所有元素
- a - b : 集合 a 中包含而集合 b 中不包含的元素
# 集合不是键值对
# 集合是无序的
# 不能通过索引获取
# 重复的元素直接丢掉,集合目前我们使用的最多的功能就是去重
set_yuz = {'yuz','鲁西西','闲人','yiguan'}
print(set_yuz)
# print(set_yuz[1]) # 会报错
print(len(set_yuz)) # 去重
set_yuz = list(set(['yuz','鲁西西','闲人','yuz']))
print(set_yuz) # split 分割
# a = 'hello world'
# b = a.split('w')
# print(b) a = 'hello/world/sofo/sooof'
b = a.split('/',1) # 数字1代表分割一次
print(a) # a 是字符串,不会变
print(b)
(五)、数据类型相互转换
1、字符串的转化
字符串转换成列表
- 字符串转换成list 的时候,str可以作为迭代对象,直接放入;也可以使用split对字符串进行切割。然后返回list
s = '1ab1cd'
print(list(s)) # ['1', 'a', 'b', '1', 'c', 'd']
print(s.split('1')) # ['', 'ab', 'cd']
字符串转换成元组
s = '1ab1cd'
print(tuple(s)) # ('1', 'a', 'b', '1', 'c', 'd')
字符串转换成字典
a='1ab1cd'
b='123456'
print(zip(a,b)) # <zip object at 0x00000000022952C8>
print(dict(zip(a,b))) # {'1': '4', 'a': '2', 'b': '3', 'c': '5', 'd': '6'} a='1ab1cdd4e5'
b='123456'
print(zip(a,b)) # <zip object at 0x00000000022952C8>
print(dict(zip(a,b))) # {'1': '4', 'a': '2', 'b': '3', 'c': '5', 'd': '6'}
字符串转换成集合
a='1ab1cd1d'
print(set(a)) # {'1', 'a', 'c', 'b', 'd'}
2、列表的转化
列表转换成字符串
- 列表里如果有int类型,字典,元祖,列表,则join方法不可用
list = ["3","d","aaa"]
print("".join(list)) # 3daaa
print(" ".join(list)) # 3 d aaa
print("!".join(list)) # 3!d!aaa
列表转换成元组
list = ['1','2','3','a',(1,2,3),1,[1,2],{"a":1}]
print(tuple(list)) # ('1', '2', '3', 'a', (1, 2, 3), 1, [1, 2], {'a': 1})
列表转换成字典
list1 = ['1','2','3','4','a',(1,2,3),5,6]
list2 = ['a','b','c','d','e','f',[1,2],{"g":"h"}]
dict1 = dict(zip(list1,list2))
print(dict1)
# {'1': 'a', '2': 'b', '3': 'c', '4': 'd', 'a': 'e', (1, 2, 3): 'f', 5: [1, 2], 6: {'g': 'h'}}
列表转换成集合
list = ['1','2','3','3']
print(set(list)) #{'3', '1', '2'}
3、元组的转化
元组转换成字符串
- 元组里如果有int类型,字典,元祖,列表,则join方法不可用
tuple = ('1','2','3','4','2','a')
print(''.join(tuple)) # 12342a
元组转换成列表
tuple = (1,2,3,4,5,'2','a')
print(list(tuple)) # [1, 2, 3, 4, 5, '2', 'a']
元组转换成字典
tuple1 = ('1', '2', '3', '4',111,(11,22,33),"")
tuple2 = ('a', 'b', 'c', 'd','e','f','h','g','i','j','k')
dict1 = dict(zip(tuple1, tuple2))
print(dict1) # {'1': 'a', '2': 'b', '3': 'c', '4': 'd', 111: 'e', (11, 22, 33): 'f', '': 'h'}
元组转换成集合
tuple1 = ('1','2','3','4',4,'4',4,1)
print(set(tuple1)) # {1, 4, '3', '1', '2', '4'}
4、字典的转化
字典转换成字符串
- 对于生成字符串,需要先生成list和tuple,然后再由list和tuple生成str
dict1 = {1:'a',2:'b',3:'c'} list1 = list(dict1.values())
print("".join(list1)) # abc tuple1 = tuple(dict1.values())
print("".join(tuple1)) # abc
字典转换成列表/元组/集合
- 字典可以使用 dict.keys() 和 dict.values() 返回迭代器,通过list和tuple直接生成列表和元祖
dict1 = {1:'a',2:'b',3:'c'}
print(list(dict1.keys())) # [1, 2, 3]
print(list(dict1.values())) # ['a', 'b', 'c'] print(tuple(dict1.keys())) # (1, 2, 3)
print(tuple(dict1.values())) # ('a', 'b', 'c') print(set(dict1.keys())) # {1, 2, 3}
print(set(dict1.values())) # {'a', 'b', 'c'} print(tuple(dict1.items())) #生成元祖为单位的元祖
# ((1, 'a'), (2, 'b'), (3, 'c'))
print(list(dict1.items())) #生成元祖为单位的列表
# [(1, 'a'), (2, 'b'), (3, 'c')]
print(set(dict1.items())) #生成元祖为单位的集合
# {(2, 'b'), (3, 'c'), (1, 'a')}
5、集合的转化
集合转换成字符串
- 集合是无序的,每次转换成的字符串值都不一定一样,也可以先转为列表或者元祖,再转换成字符串
set1 = {"1","2","ac"}
print("".join(set1)) # 2ac1
print(type("".join(set1))) # <class 'str'>
集合转换成列表/元组
set1 = {1,2,3,4,5,6}
print(list(set1)) # [1, 2, 3, 4, 5, 6]
print(tuple(set1)) # (1, 2, 3, 4, 5, 6)
集合转换成字典
- 无意义的映射,不推荐
set1 = {1,2,3,4,5,6}
set2 = {'a','b','c','d'}
print(dict(zip(set1,set2)))
# {1: 'd', 2: 'a', 3: 'b', 4: 'c'}
三、控制流程
(一)、条件语句
if条件判断
- 分支结构,常用的表现方式:
- if(条件表达式):......
- if(条件表达式):......else:......
- if(条件表达式):......elif(条件表达式):......elif(条件表达式):......else:
- 分支结构,常用的表现方式:
# if的写法(else可以省略)
if (条件表达式):
pass
else:
pass
if (条件表达式):
pass
elif (条件表达式):
pass
else:
pass
# 例如:
username = "yuze"
if username == "yuze" or username == "yuzewang":
#缩进表示条件满足以后需要执行的子代码,是一个分支
print("登录成功")
elif username == ""
print("请输入用户名")
elif username == "Demo"
print("没有该用户")
else
print("登录失败")
if语句用于验证某个条件
- 当条件为真时,运行if下面的代码块,否则运行else下面的代码块
- 条件当中,只要执行了一个分支,其它分支就不会继续执行了
- 条件表达式:要得到的值是一个bool类型,True, False
使用if需要注意的点
- 所有分支流必须以if开头
- 语句中的else可以省略
- if与elif后面必须加条件表达式,else后面不能加条件表达式
- 一个判断分支下只有一个if,一个else,可以有多个elif
- 分支下按顺序执行代码,只要执行了一个分支下的代码,其他的分支则都不会执行
(二)、程序debug调试
- 是暂停代码的运行去获取现在的数据状态
- pycharm中的debug
- 先打断点
- 再执行debug
- 下一步按钮
- 查看数据
- 打断点,是告诉程序我应该在哪里暂停
(三)、while循环
循环控制流
- 循环语句,用于验证某个条件
- 当条件为真时,运行循环下的代码块,否则结束循环
- 分类:
- while 循环
- for 循环
while循环作用:用来重复执行某个操作
while 语法
while 判断条件:
执行代码
# 例如:
times = 0
while times < 999:
print("我说了{times}次")
times = times + 1
continue: 表示手工进入下一个循环体,进入下次循环
break:表示手工强制退出整个while循环
(四)、for循环
作用:
- 用来遍历对象
- 从对象的第一个元素到最后一个元素,依次访问
- for循环会自动+1
语法
- for 元素 in 数据集合:执行代码
- 数据集合可以是:列表,元组,字典,字符串,也可以是指定的数据范围
- for循环嵌套,子循环执行完,才会回到母循环执行
for 迭代变量 in 字符串|列表|元组|字典|集合:
代码块
# 例如:
add = "http://c.biancheng.net/python/"
#for循环,遍历 add 字符串
for ch in add:
print(ch,end="")
continue:手工进入下一个循环体,进入下次循环
break:手工强制退出整个while循环
break
- 常用在循环结构中
- 在循环中遇到break,就跳出循环
continue
常用在循环结构中
在循环中遇到continue,就跳出本次循环,继续下一次循环
(五)总结知识点
- for经常用到的场景:如果有一个现成的列表,字符串,字典,就用for
- while经常用到的场景:不知道什么时候结束循环
- 同时获取列表的索引和值
for i,value in enumerate(list):
print(i, value)
- 同时获取字典的键和值(常用)
for k,v in mdict.items():
print(k, v)
- 获取所有的value
for value in mdict.values():
print(value)
- 获取所有的key
for key in mdict.keys():
print(key)
for k in mdict:
print(k)
range() 函数
- 表示循环某一个数据段
- range(start,end,step),与切片类似,包前不包后
- 打印100遍
for i in range(100):
print(i)
四、函数和函数参数
(一)、函数定义和调用
1、函数的定义
函数的概念:以数学函数来理解
作用:传入一个自变量,会得到一个另外的变量,这个变量会根据自变量变化而变化
用于存储一段代码。 是封装
定义函数关键字:def
为什么要写函数:方便好用、复用性高
函数名:属于标识符,遵循标识符的命名规则:
- 函数的名称是一个标识符:数字、字母、下划线,不能是内置关键字
- 函数名遵循蛇形命名:下划线命名
- 函数名称要见名知义
- 函数命名的重要性:函数的名称会告诉读代码的人:这个函数的作用是什么
语法:
def 函数名(参数):
函数内部功能代码一
函数内部功能代码二
函数内部功能代码三
函数内部功能代码四 def add(a,b):
print(a+b)函数中的代码如何运行?
- 函数定义时,函数的代码不会被执行,只有当函数被调用时,函数中的代码才会被执行
不要在一个文件中定义两个同名函数,后面的会覆盖前面的
def add (a,b):
print(a+b)
def add (a,b):
print(a-b)
add(1,2) # -1
2、函数的调用
使用函数的过程叫做调用函数;调用的时候会给变量赋值,即变量 = 值
调用方法:
函数名()
函数的相互调用
- 在函数中调用另外一个函数
- 函数调用是去执行函数体内部逻辑
- 避免两个函数相互调用
- 不要调用自己
(二)、函数的返回值
- return 的作用:
- 返回值数目 = 0;返回 None
- 返回值数目 = 1:返回object
- 返回值数目 > 1:返回tuple
- 疑问:为什么要用return?什么时候用return?
- 根据需求,当需要返回的时候就返回,不需要返回的时候就不返回。
- 注意点:
- 1、return 是用来给函数返回结果的。
- 2、当函数执行到return 时函数执行结束。
- 3、函数没有定义return,默认的返回值为None
- 现在有两件事,写成两个函数
(三)、函数参数
1、参数的定义
- 函数名后面的括号汇总定义参数
2、形参与实参
- 在函数定义的时候出现,是变量名,是自己定义的
- 调用时实际传递的参数为:实参,是函数调用时出现的,实际参数是将要赋给变量名(形参)的值
- 实参和形参要配对,成对出现的,下面情况都是不行的
- 只有实参,没有形参
- 只有形参,没有实参
def add (a,b):
print(a+b)
return(a+b)
add(1,2) # a,b是形参, 1,2 是实参
位置参数
- 函数的形参和实参是成对出现的,一一对应的
- 函数调用的时候一定要检查好参数的个数
- 位置参数概念
- 形参和实参的这种位置关系叫位置参数
def add (a,b):
print(a+b)
return(a+b)
add(1,2) # 1对应a, 2对应b
关键字参数
- 关键字参数,函数调用的时候,给实际参数贴标记,标记是形参的变量名
- 通过关键字参数,可以不按顺序配对
- 关键字参数要放在位置参数的后面
- 关键字参数的作用:当参数很多时,可以使用
def add (a,b):
print(a+b)
return(a+b)
add(b=3,a=2)
默认参数
- 在函数定义的时候,给形式参数一个默认的值
- 调用函数的时候,可以不用赋值给默认参数
- 使用默认参数:可以少些实际参数
- 放在位置参数后面
def add (a,b=8):
print(a+b)
return(a+b)
不定长参数
- 不定长参数表示方式: * **
- * 当在一个形参前加*,他会收集所有剩下没有配对的实际参数(位置参数),把剩下的数据组成一个元组
- *args 存放很多位置参数
def add (a,*b):
print(a)
print(b)
add(1,2,3,4) # 1,(2,3,4) def add (a,*b):
print(a)
print(b)
add(1,2,3,4,c=1) #报错:默认参数要放到位置参数后面,不定长参数放到位置参数后面
**只能收集关键字参数
**kwargs 存放很多关键字参数
将数据转换为字典的形式
def add (a,**b):
print(a)
print(b)
add(1,c=1,d=2) # 1 {'c': 1, 'd': 2}
不定长参数的作用
- 在参数定义的时候,不知道有多少个实际参数(关键字参数)
拆包:
- 列表、元组拆包
- 会拆成位置参数
- 函数定义当中args 表示不定长的位置参数,在调用的时候,叫做拆包、解包
- 调用的时候,把 一个列表或元素变量传入函数,在前面加,就可以比那成多个值
def marry(male,female):
print(male)
print(female) couple = ("老王","小星星") marry(*couple)- 字典拆包
- 会拆成关键字参数
couple = {"male":"小王","female":"老刘"} marry(**couple)
- 列表、元组拆包
(四)、函数作用域
- 是局部作用域
- 在定义函数时,设置的变量为局部变量
- 局部变量不能在全局作用域获取
- 函数内部局部作用域可以用全局变量
- 在函数外部不能修改函数内部的变量
- 在函数内部可以修改全局变量,不过需要用global声明是全局变量 例如:global c
(五)、内置函数
print :输出
input :输入
type :查看数据类型
range :生成数据
id :获取数据内存地址
int、float、str、bool、list、dict、tuple、set :代表对应的数据类型,转换数据类型
max :获取最大的值,可以传多个参数,可以传列表
min :获取最小的值,可以传多个参数,可以传列表
sum :求和
enumetate:
# enumerate() 将列表中的元素及其位置转换为成对的元组
m_list = ['aa', 'bb', 'cc', 'dd']
print(list(enumerate(m_list)))
# [(0, 'aa'), (1, 'bb'), (2, 'cc'), (3, 'dd')] print(list(enumerate(m_list, start = 1)))
# [(1, 'aa'), (2, 'bb'), (3, 'cc'), (4, 'dd')]
eval :可以去掉一个字符串的引号
m_str = "6>7"
print(m_str)
print(eval(m_str)) # False
m_str = '{"username":"yuz","age":18}'
print(m_str) # {"username":"yuz","age":18}
print(type(m_str)) # <class 'str'>
print(eval(m_str)) # {'username': 'yuz', 'age': 18}
print(type(eval(m_str))) # <class 'dict'>
filter :过滤某些数据 filter(调用函数,列表)
li = [2,3,4,5,6,7]
def get_odd(value):
if value % 2 == 0:
return True
return False
res = filter(get_odd, li)
print(list(res)) # [2, 4, 6]
- map :
li = [2,3,4,5,6,7]
def square(value):
return value ** 2
res = map(square, li)
print(list(res)) # [4, 9, 16, 25, 36, 49]
- zip :
li_1 = ["yuz","hello","world"]
li_2 = [43,12,15]
print(list(zip(li1,li2))) # [('yuz', 43), ('hello', 12), ('world', 15)]
a = zip(li1, li2)
print(dict(a)) # {'yuz': 43, 'hello': 12, 'world': 15}
(六)、模块和包
模块
- 模块,就是一个带 .py 后缀的python 文件,一个模块里面会有很多的函数,类
- 模块名称:是一个标识符,符号标识符命名规则
- 数字、字母、下划线,不能以数字开头,不能是关键字
- 模块名称命名一般是使用下划线的形式命名,驼峰, d1_review.py
- 模块名称不能和 python 内置的模块名称重合
- 模块作用:
- 有逻辑的组织python代码
- 把相关功能的代码写到一个模块里能让代码更好用,更易懂
包
- 包,package,就是一个python文件的文件夹,里面会有一个或多个模块
- 包含一个_init_.py 模块的文件夹,这个模块可以什么都不定义,可以只是一个空文件夹
- 标准库,第三方库,实现特定功能的代码集合,一个模块,也可以是一个包
- python3 新版本,不带_init_.py 同样可以作为包使用
模块导入
是模块间变量和函数的互相使用 ,需要使用 import 的关键字
import ... 后面只能跟 模块,不能跟函数,变量
from .. import ... 后面可以跟模块,函数,类,变量
导入自己的模块,别人的第三方模块,一般使用from import ,不用import..
google内部约定,导入模块只导入模块这一层,然后使用 模块名.函数名() 来调用函数
from class_9_file import demo01 demo01.test01_fun()
import .. 调用函数的时候需要些很长的前缀,比较麻烦
不建议使用:from... import *
- 导入模块或者包里面,所有的类、函数、变量
- 导入所有,如果重命没有解决方法
as 重命名 - 避免同名函数冲突
导入时导入到模块这一层,使用时使用模块名.函数名
使用别名
- 别名就是重命名,就是原函数名很长,为了方便使用函数
from class_9_file import demo01 as d d.test01_fun()
不要用相对导入,要绝对导入,就是从根目录开始导入
五、文件及路径
(一)、文件
1、打开文件和关闭文件
打开文件,使用内置函数 open()
- open(" path/文件名.后缀 “)
特别注意:打开文件不管进行什么操作后,一定要关闭文件,否则会出现数据不对,或者写入内容不生效,文件无法再次被打开等情况
f = open("python32.txt")
f.close()
为了避免忘记关闭文件,可以使用with语句,操作完成后会自动关闭文件
with open('python32.txt','r',encoding='utf8') as f:
print(f.read()) with open('python32.txt','a',encoding='utf8') as f:
print(f.write())
不在同一路径下要用绝对路径,windows要加 r 防止转义,有反斜杠,mac不用加
with open(r'J:\学习资料\Study\PythonAndSelenium\柠檬班python自动化课程\python32_API\class_09_file\python32.txt') as f:
print(f.readline())
2、读取文件
mode 打开方式
- r 以只读方式打开文件(默认),一般用于文本文件,如:txt。文件指针默认放在文件开头
- b 以二进制格式打开文件。一般用于非文本文件,如:图片、视频
- rb 以二进制的形式打开并读取
read() 读取
with open("python32.txt", mode = 'r', encoding = 'utf8') as f:
print(f.read()) with open('1.png', mode= 'rb') as f:
print(f.read())
readline() 读取一行
with open('python32.txt', encoding = 'utf8') as f:
print(f.readline())
readlines() 读取所有行,会以列表的形式展示
with open('log.txt', encoding = 'utf8') as f:
print(f.readlines()) # 可以显示换行符
3、写入文件
mode 写入方式
- w 新建写入
- w比较危险,如果之前已经有同名的文件,用w会覆盖之前的内容,w只能用于新建写入
- a 追加写入
- 如果文件名不存在,是先新建再写入;如果文件名存在,则为追加
- wb 以二进制打开一个文件用于只写
- 如果文件名存在,则覆盖,不存在,则新建写入
- ab 以二进制打开一个文件用于追加
- 如果文件存在,文件指针会放在文件结尾处
with open('python32.txt', mode = 'w', encoding = 'utf8') as f:
f.write('裴纶') with open('python32.txt', mode = 'a', encoding = 'utf8') as f:
f.write('哈哈哈')
- + 表示可以同时读写某个文件
- r+ 可读,可写
- w+ 可读,可写
- a+ 可读,可写
- w 新建写入
(二)、路径
1、路径
sys . path 包含项目开始根目录路径和 python 内置的目录路径
- 模块导入的搜索路径: sys.path
- 模块导入不了时可以用来检查
- python去查找包或模块,相当于python里的地图
- 返回的是一个列表
- 模块导入的搜索路径: sys.path
os 是 python 内置的模块需要用 import 导入: import os
找模块
- 项目开始根目录
- python内置目录
- 不建议将写的模块存放在python的安装目录下
- python目录主要是放外部的库或第三方的模块
2、路径处理
python中一般不直接写入绝对路径, 而是通过代码获取
获取当前文件的路径:
abs_path = os.path.abspath(_file_)
_file_ 表示运行的文件的名称
获取当前文件的目录路径: 两种写法,用第一种绝对路径
dir_name = os.path.dirname(abs_name)
dir_name = os.path.dirname(_file_)
获取不与当前文件同一个目录下的文件路径
- 1 .先获取当前文件的绝对路径
- 2 .获取当前文件的目录路径
- 3 .当前文件的目录路径和该文件拼接
比如,获取pac01 下面的 demo.txt:
txt_file_path = os.path.join(dirname, 'pac01', 'demo.txt') 读取图片文件(二进制格式)
dir_name = os.path.dirname(os.path.abspath(file))
png_pic = os.path.join(dir_name,'1.png')
f = open(png_pic,mode='rb')
print(f.read())
f.close()
3、路径操作
os.path.abspath() 获取绝对路径
os.path.dirname() 获取文件/目录所在路径
os.path.join(a, b) 连接两个部分的路径,组成一个完整路径
os.getcwd() 获取当前工作路径
os.chdir() 切换工作路径
os.mkdir() 在某个目录下创建一个新目录
os.rmdir() 删除一个目录
os.listdir() 获取当前路径下的目录,返回列表格式数据
os.path.isdir() 判断当前文件是否是目录,返回布尔值
os.path.isfile() 判断当前文件是否是文件,返回布尔值
六、异常
(一)、异常处理
- 异常
- 当程序运行中检测到一个错误时,无法继续执行,出现一些错误提示,这就是异常。
- 程序遇到异常不会再执行,我们要改变程序碰到异常的行为
(二)、异常类型的捕获
语法一:try...except....
程序先执行try中的代码,一旦try中某个代码报错, 会直接跳到except,try剩下的代码不会执行
try:
要执行的可能发生异常的代码
except:
程序发生异常后,你希望程序做的事情 try:
1/0
except IndexError as e:
print(e)
# 其中as e可以在后面用来展示异常信息,但不能展示异常类型
语法二:try...except....finally
try:
1/0
except ZeroDivisionError as e:
print("不能除以0")
finally:
print("无论异常与否,都会继续执行的代码") # 运行结果:
# 不能除以0
# 无论异常与否,都会继续执行的代码
try...except...else
try:
1 / 0
print("正常执行的代码")
except ZeroDivisionError as e:
print("不能除以0")
else:
print("代码没有报错才会执行")
print("正常执行的代码的后面部分")
# 运行结果:
# 不能除以0
(三)、多异常类型的捕获
- 多种异常出现时,可以统一处理的就用下面的方式一,处理方式不一样的就用方式二
方式一:
try:
{'name':'yez'}['age']
a = 1/0
lst = ['yz','yr']
lst[3]
except(ZeroDivisionError, IndexError, KeyError) as err:
print(err)
print('hello')
except ImportError as e:
print()
方式二:
try:
{'name':'yez'}['age']
a = 1/0
lst = ['yz','yr']
lst[3]
except ZeroDivisionError as err:
print(err)
except IndexError as err:
print('index error')
except KeyError:
print('key error')
(四)、抛出异常
raise 主动抛出异常
def adult_add(a, b):
# 两个数相加, a, b 一定要大于18, 否则就不能运行
if (a < 18) or (b < 18):
raise ValueError('参数必须大于18')
c = a + b
return c
print(adult_add(3, 4))
print('函数执行完成。') # 上面一行报错,这行不会打 try:
adult_add(3, 4)
except:
print('函数执行完成。') # 结果会打印:函数执行完成。
(五)、断言 assert
断言: assert
断言的作用:判断真假
断言的时候,如果断言成功,程序继续执行
如果断言失败,程序终止运行,本质上断言失败会触发一个异常类型:AssertionError
断言,主要用在预期结果和实际结果的比对
height = int(input('输入身高:'))
print(height > 180) # False
assert height > 180
print("断言有结果")
七、面向对象
(一)、类(Class)
什么是类:
- 是指所有符合某种特征的个体的集合
- 类(Class) 是用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。
类的表示:(下面三种写法作用完全一样)
class 类名称:
# 类当中的内容
属性 ==》 特征
行为 class 类名称():
pass class 类名称(object):
passclass Dog:
# 类内容
tailed = True def say(self):
print('汪汪。。。')
类的命名
- 符合标识符命名规则
- 字母数字下划线,不能是关键字,要有意义
- 规范:大驼峰,SingleDog
使用 类 的好处
- 方便复用(如果你用函数写,就要复制整块代码,增加了代码量,增加了出错率)
- 方便扩展(函数写段代码,若要升级、扩展,都十分复杂,容易出错,用类来扩展,则方便清晰)
- 方便维护(因为类是把抽象的东西映射成我们常见的,摸得到的东西,容易理解,维护也方便)
(二)、对象
什么是对象:
- 对象指的是某个类当中的一个成员,一个个体
- 对象是从类当中生成的, ==》 类是一个模型,是一个生产图纸。
- 对象就是类的具体实例
- 类是函数的定义,对象是函数的调用
- 实例、对象、object 都是同一个东西
class Dog:
# 类内容
tailed = True def say(self):
print('汪汪。。。') zhonghua = Dog()
print(zhonghua) # 是对象 <__main__.Dog object at 0x00000000022724A8>
print(Dog) # 是类 <class '__main__.Dog'> # Dog 不加括号的时候是类
zhonghua = Dog
print(zhonghua) # <class '__main__.Dog'>
(三)、属性和方法
- 属性就是指类或者对象的特征。名词
- 方法就是指类或者对象的行为。动词
- 属性:
- 类属性(类变量):类当中每一个成员都具备的特征,类和对象都可以获取类属性
- 实例属性(实例变量)、对象属性:类当中的成员不一定都具备的特征,是对象独有的,自己具备
- 方法:
类方法:每一个成员或者整个类都能调用的行为
实例方法、对象方法:只能是需要一个单独的成员调用的行为,不能是整个类调用
- 不要用整个类去调用实例方法
- 实例方法在定义的时候自带一个参数:self,
- 但是实例方法在调用的时候不需要传 self 这个参数的实际参数
class Dog:
# 有尾巴
# 类属性
tailed = True # 实例方法
def say(self):
print('汪汪汪。。。') # 对象
teddy = Dog() # 类属性的获取
print(Dog.tailed) # True # 对象获取属性
print(teddy.tailed) # True # 属性可以后天修改
Dog.tailed = False
print(Dog.tailed) # False
print(teddy.tailed) # False teddy.tailed = '有时候有尾巴,有时候没有'
print(Dog.tailed) # False
print(teddy.tailed) # 有时候有尾巴,有时候没有 # 类方法的调用
# Dog.say() # 会报错
# Dog.say('abc') # 不要用整个类去调用实例方法
# teddy.say('abc') # 会报错
teddy.say() # 汪汪汪。。。
(四)、对象的初始化
一个对象:除了整个类都具备的属性,还有自己的特征。 对象自己的特征就叫实例属性或者对象属性。
每个对象都有自己不同的实例属性,可以在对象生成的时候传入实际参数,这个实际参数就是实例属性,传入实际参数时需要有对应的形式参数,这些形式参数不能在类后面直接定义,这里就定义了一个特别函数,方法,_init_,在这里面定义好的形式参数,最终在对象初始化的时候传入实际参数,这个实例属性产生的过程就叫对象的初始化。
传入的实际参数是在什么时候调用的???
teddy = Dog(name = 'teddy', color = 'blue') 自动调用 _init_
不需要写 Dog._init_()TODO: 一定不要写成 _int_
class Dog: tailed = True # 定义一个特别函数,方法,定义好的形式参数,最终在对象初始化的时候传入实际参数
def __init__(self, name, color):
"""初始化函数,初始化方法"""
# 自定义对象产生的过程
# 实例属性的产生 self.name 定义一个叫做 name 的实例属性
self.name = name
self.color = color
def say(self):
print('汪汪汪。。。') teddy = Dog(name = 'teddy', color = 'blue')
teddy.say() # 获取实例属性
print(teddy.color) # 类不能调用实例属性
# print(Dog.color) # AttributeError: type object 'Dog' has no attribute 'color'
实例化
通过一个类去创建一个对象,就是实例化。
实例化是产生对象的过程
实例化就是函数的调用
产生对象,实例化对象的时候,会自动调用 _init_ 这个方法
self.name = name
self.name ==> 实例属性
name ====> 参数, teddy 值。
name 这个name是变量,和类和对象没有关系
什么是 self :
所谓的self,可以理解为自己,就是我们的实例本身,代表实例对象,谁去调用代表谁。
Kitty 这个实例对象调用,self就代表Kitty
jingel 这个实例对象去调用,self就代表jingel
某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给 self,只需要传递后面的参数即可
self 可以改成其他名字,但不建议改,你改了别人就不知道具体的含义了
class Dog: tailed = True # 定义一个特别函数,方法,定义好的形式参数,最终在对象初始化的时候传入实际参数 def __init__(self, name, color='grey'):
"""初始化函数,初始化方法"""
# 自定义对象产生的过程
# 实例属性的产生 self.name 定义一个叫做 name 的实例属性 # dog.name = name # 不能这样写,函数里面不能使用全局变量,这个时候 dog 这个对象还没有产生出来
# Dog.name = name # 也不能这么写,不能所有的狗都叫同一个名字 self.name = name
self.color = color
print(self) def say(self):
print('汪汪汪。。。') dog = Dog('teddy')
print(dog.color) # grey
# dog
print(dog) # self 和 dog 对象是同一个地址 # ha = Dog('teddy')
# print(ha.color) # grey
# # dog
# print(ha) # self 和 ha 对象是同一个地址
(五)、实例方法、类方法、静态方法
1、实例方法:
- 定义:
- 实例方法直接定义在类中
- 第一个参数是 self (必须要写),
- 实例方法的访问
- 只有该类的实例对象都可以访问,访问实例方法的时候会自动将对象本身当成参数,传给self接收
- 在类和对象当中,实例方法是用的最多的。
- 如果不知道该定义成实例方法,类方法还是静态方法,就定义成实例方法
- 调用方法:
- obj.方法名()
- 实例.方法()
2、类方法:
定义:
使用装饰器 @classmethod。第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法(不能传实例的属性和方法)
调用:
- 实例对象和类对象都可以调用
应用场景:
- 需要站在类的角度执行某个行为时,那么就应该定义为类方法
类方法调用
- 类.类方法()
3、静态方法:
定义:
- 使用装饰器 @staticmethod 参数随意,没有 self 和 cls 参数,但是方法体中不能使用类或实例的任何属性和方法
调用:
- 实例对象和类对象都可以调用。
应用场景:
- 存放逻辑代码,内部不需要引用类属性和实例属性
- 当想在一个类当中定义一个方法,和这个类或者对象没有直接的关系。
- 你在方法当中,没有使用到类或者是对象。
静态方法调用:
- 类和对象,都可以调用静态方法
静态方法存在的理由:
- 放在类里面方便管理
def say_static(times): # 放在这里是普通的函数,和放在类里面效果是一样的,只是调用时这个直接调用,调用类里面的需要加前缀
print(f'汪汪。。。{times} 声')
class Dog:
tailed = True
# 定义一个特别函数,方法,定义好的形式参数,最终在对象初始化的时候传入实际参数
def __init__(self, name, color='grey'):
"""初始化函数,初始化方法"""
self.name = name
self.color = color
print(self)
# 实例方法
def say(self, times):
print(f'{self}汪汪汪。。。{times} 声')
# 静态方法
@staticmethod
def say_static(times):
print(f'汪汪汪。。。{times} 声')
# # 类方法。进化
# def jinhua(self):
# print('狗类正在进化')
# Dog.tailed = False
# 声明:这是一个类方法
# 固定写法
@classmethod
def jinhua(cls):
print('狗类正在进化')
Dog.tailed = False
haha = Dog('haha')
yiyi = Dog('yiyi')
# print(haha.tailed) # F
# print(yiyi.tailed) # F
# Dog.jinhua() # jinhua()是实例方法,不能使用类去调用
# print(haha.tailed)
# print(yiyi.tailed)
# 类方法的调用
# Dog.jinhua() # Dog 加括号表示对象,不加括号表示类
# haha.tailed
# haha.jinhua()
# print(haha.tailed)
#
# haha.say(5)
# 静态方法的调用,类和对象,都可以调用静态方法
haha.say_static(5)
Dog.say_static(6)
# 普通函数版
say_static(7)
(六)、继承
(1)、类的继承
定义类两种方式的区别:
# Python2 中称为经典类,在python3 中默认继承 object
class MyTest:
pass # python2 中称为新式类。
class MyTest(object):
pass
# 注意点:python3 中上面两种定义方法没有区别,都是继承 object 这个父类
在python3 的继承中,所有的类都默认继承自 object 这个基类。
子类通过继承可以获得父类的属性和方法。
被继承的类叫父类(也叫基类),继承的类叫子类
注意:私有属性不能继承
作用:
- 子类通过继承可以获得父类的属性和方法,提高开发的效率及代码的复用率
# 普通写法定义手机类和智能手机类
class Mobile:
def __init__(self, model, color='blacd'):
self.model = model
self.color = color def call(self):
"""打电话"""
print(f"{self} 手机正在打电话。") class SmartPhone:
def __init__(self, model, color='blacd'):
self.model = model
self.color = color def call(self):
"""打电话"""
print(f"{self} 手机正在打电话。") def play_game(self):
print("玩游戏") # 使用继承
class Mobile():
def __init__(self, brand, model, color='blacd'):
self.model = model
self.color = color
self.brand = brand def call(self):
"""打电话"""
print(f"{self} 手机正在打电话。") class SmartPhone(Mobile): def play_game(self):
print("玩游戏") # iphone = SmartPhone()
# iphone.play_game() # 这里会报错,初始化的时候需要调用__init__方法,自己没有去找父类,父类的__init__需要传参数 iphone = SmartPhone('iphone12', 'apple')
iphone.play_game()
(2)、超继承
重写父类方法
- 重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中的同名方法
- 如:同样是打电话,第一版手机只能大语音电话,最新版手机可以打视频电话
调用重名的父类方法
- 子类重写了父类的方法之后,如何在子类中再调用父类的方法:
- 方式一:父类名.方法名(self)
- 方式二:super().方法名()
class Mobile():
def __init__(self, brand, model, color='blacd'):
self.model = model
self.color = color
self.brand = brand def call(self):
"""打电话"""
print(f"{self} 手机正在打电话。") class SmartPhone(Mobile):
def __init__(self, model, brand, color='red', pixel = 2000):
# self.model = model
# self.color = color
# self.brand = brand # 这三行代码父类中有,可以使用 super()
super().__init__(brand, model, color) # 使用 super() 直接调用父类的方法
self.fiveG = True
self.pixel = pixel def play_game(self):
print("玩游戏") def call(self):
"""智能手机打电话"""
print('开视频')
super().call() # super 函数的使用
smart = SmartPhone('p40','huawei')
print(smart.pixel)
smart.call()- 子类重写了父类的方法之后,如何在子类中再调用父类的方法:
(七)、动态获取属性
获取对象属性的时候,如果对象中没有这个属性,代码就会报错
可以使用 getattr( 对象, 属性名称 , 默认值) 动态获取属性,并在属性后面传入一个默认值,如果对象没有这个属性就会显示默认值,代码就不会报错
还可以动态修改属性,使用 setattr( 对象, 属性名称 , 属性值)
class Mobile: def __init__(self, brand, model):
# 先天初始化过程中形成的属性
self.brand = brand
self.model = model def call(self):
print('正在打电话。。') iphone = Mobile('apple', 'xr')
# 获取属性
# print(iphone.brand)
# 修改属性
# iphone.brand = 'aple' # 定义新的实例属性
# 后天养成的特性
# iphone.video = '美颜'
# print(iphone.video) # 获取一个不存在的属性
# 如果获取不存在的属性,代码会报错
# print(iphone.games) # AttributeError: 'Mobile' object has no attribute 'games' # 动态获取属性
# getattr 内置函数 # print(getattr(iphone, 'games')) # 还是报错:AttributeError: 'Mobile' object has no attribute 'games'
# default ,如果获取不到属性名,传入 default 默认值,就不会报错了
# getattr 不会修改原来的对象的属性
print(getattr(iphone, 'games', '吃鸡')) # print(iphone.games,) # 还是会报错,因为iphone 没有games属性 # 动态修改属性
setattr(iphone, 'games', '王者荣耀')
print(iphone.games) # 王者荣耀
python接口测试自动化之python基础语法的更多相关文章
- web前端学习python之第一章_基础语法(二)
web前端学习python之第一章_基础语法(二) 前言:最近新做了一个管理系统,前端已经基本完成, 但是后端人手不足没人给我写接口,自力更生丰衣足食, 所以决定自学python自己给自己写接口哈哈哈 ...
- web前端学习python之第一章_基础语法(一)
web前端学习python之第一章_基础语法(一) 前言:最近新做了一个管理系统,前端已经基本完成, 但是后端人手不足没人给我写接口,自力更生丰衣足食, 所以决定自学python自己给自己写接口哈哈哈 ...
- 测试不得不知的python编程小技能-----升级版基础语法和优秀的编码习惯
编程和学习python,最后快速上手.能写小工具,写自动化用例这类要求对鹅厂的测试人员来说都是一些基础的必备素质,但是一个优秀的测试,也是有着一颗开发完美测试工具的心的.但是罗马不是一天构建成,特别是 ...
- Python语言学习前提:基础语法
一.变量 1.变量:存储数据.存储数据需要对应内存空间,基于变量的数据类型,解释器会分配指定内存,决定什么数据被存储到内存中. 变量数据类型:整数.小数.字符. 2.变量赋值:变量在使用前必须赋值,赋 ...
- python接口测试自动化框架-发送邮件,邮箱报错: 535 Error, authentication failed
1.无意中把腾讯企业邮箱设置为安全登录,接口测试自动化发送邮件,不能被正常接收.错误信息为:535 Error, authentication failed. 原因:认证安全登录后,原来新的邮箱代码传 ...
- Python开发【1.1 基础语法】
1.Python语言特点 优点: ①.丰富的库 ②.简单.开源 ③.支持面向对象编程 ④.解释性语言,无需编译 ⑤.高层语言,不用考虑内存问题 ⑥.可移植性好,不依赖于操作系统 缺点: ①.运行效率较 ...
- 编写高质量Python程序(三)基础语法
本系列文章为<编写高质量代码--改善Python程序的91个建议>的精华汇总. 关于导入模块 Python的3种引入外部模块的方式:import语句.from ... import ... ...
- Python+selenium自动化测试之浏览器基础操作
**前言** 本文主要讲解webdriber框架,Selenium 就像真实用户所做的一样,Selenium 测试可以在 Windows.Linux 和 Macintosh上的 Internet ...
- Python接口测试自动化说明及代码实例:含get、post、put、delete等方法
一.接口说明文档 环境准备: 安装火狐 安装插件: httprequester https://addons.mozilla.org/en-US/firefox/addon/httprequester ...
随机推荐
- Linux搭建Gitlab(Docker版)
1.拉取gitlab的docker镜像 #这里使用gitlab的社区版 docker pull gitlab/gitlab-ce 2.启动gitlab容器实例 docker run -d -p 44 ...
- Swap常用操作与性能测试
Swap分区通常被称为交换分区,这块儿分区位于硬盘的某个位置,当系统内存(物理内存)不够用的时候,如果开启了交换分区,部分内存里面暂时不用的数据就会Swap out(换出)到这块儿分区:当系统要使用这 ...
- zabbix脚本发送邮件告警
目录 zabbix邮箱告警 内部使用第三方邮箱发送邮箱告警 zabbix使用第三方邮箱发送告警 通过脚本使用第三方邮箱发送邮箱告警 zabbix邮箱告警 环境说明: zabbix服务端 192.168 ...
- python程序设计PDF高清完整版免费下载|百度云盘
百度云盘:python程序设计PDF高清完整版免费下载 提取码:bvsz Python 程序设计基础难易程度适中.除Python应用开发基础知识之外,还适当介绍了Python标准库以及内置对象的工作原 ...
- “随手记”开发记录day16
今天先对前两天增加的“修改”功能进行测试.然后进行功能的明显划分,丰富账单的添加和显示方法.
- 蓝奏云数值验证码识别,python调用虹鱼图灵识别插件,超高正确率
识别验证码一直是本人想要做的事情,一直在接触按键精灵,了解到有一个虹鱼图灵识别插件专门做验证码和图像识别,原理就是图片处理和制作字库识别,制作字库我一直觉得很麻烦,工程量太大.不管怎样,它能用能达到我 ...
- ECMAScript6新增数据类型symbol数据类型
25.Symbol目的:为了解决对象之间属性名冲突的问题,Symbol它是引用数据类型. Symbol( ),它代表着一个独一无二的值 [name]: '小红',//加中括号代表默认创建了一个Symb ...
- C# 8.0 的新特性概览和讲解
本文转自 https://blog.csdn.net/hez2010/article/details/84036742 C# 8.0 的新特性概览和讲解 前言 新的改变 可空引用类型(Nullable ...
- Linux expect用法介绍
1.expect是linux中一个交互命令,一般在 /usr/bin/expect路径下,如果该路径未加入到环境中需要先添加,其作用场景常用于交互执行输入指令 常用命令: expect 获取上一命令执 ...
- 【Spring注解驱动开发】如何实现方法、构造器位置的自动装配?我这样回答让面试官很满意!
在 冰河技术 微信公众号前面的文章中,我们介绍了如何使用注解来自动装配Spring组件.之前将的都是在来的字段上添加注解,那有没有什么方法可以实现方法.构造器位置的自动装配吗?今天我们就一起来探讨下如 ...