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 5.11 保留小数点后两位 0.25 25.00% 百分比格式 aa aa 左对齐(宽度为10) aa 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] = value -
update() : 将一个字典的所有元素更新到另一个字典中
# 简单理解 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方法不可用
list1 = ["3","d","aaa"] print("".join(list1)) # 3daaa print(" ".join(list1)) # 3 d aaa print("!".join(list1)) # 3!d!aaa
-
列表转换成元组
list1 = ['1','2','3','a',(1,2,3),1,[1,2],{"a":1}] print(tuple(list1)) # ('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'}}
-
列表转换成集合
list1 = ['1','2','3','3'] print(set(list1)) #{'3', '1', '2'}
3、元组的转化
-
元组转换成字符串
- 元组里如果有int类型,字典,元祖,列表,则join方法不可用
tuple1 = ('1','2','3','4','2','a') print(''.join(tuple1)) # 12342a
-
元组转换成列表
tuple1 = (1,2,3,4,5,'2','a') print(list(tuple1)) # [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): pass
class 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) # 王者荣耀