1. 深拷贝和浅拷贝
1.1、变量、对象和引用
类型属于对象,而不是变量:变量名没有类型,对象才有类型,变量实质上是指向对象所在内存空间的指针,变量只是对对象的引用。
不同赋值,因为变量没有类型,所以实质上只是修改变量a为对不同类型的变量的引用。变量总是一个指向对象的指针,而不是可改变的内存区域的标签。给一个变量赋新值,并不是替换原始的对象,而是让这个变量去引用别的对象。通俗的讲就是一个变量被赋新值,只会影响这个变量,而不会影响其共享对象的变量。
a = 3
print(a)
# 输出为3
1.2、对象的垃圾收集
对象包括两个头部信息:类型标志位和引用计数器。
类型标志位指对象的类型,如int,str
引用计数器指当前引用该对象的数目,当数目为0时,对象的空间被自动回收。
a = 'hello python'
print(a)
a = 3 # --> 'hello python'被回收
print(a)
1.3、共享引用(共享对象)
两个变量同时引用同一对象
a = 'hello word'
b = a
print(a)
print(b)
1.4、共享引用和相等
== 比较两个被引用的对象是否具有相同的值
is 比较实现引用的指针是否相同,即是否引用同一对象,是否为共享引用。
a = [1, 2]
b = a
print(a == b)
print(a is b)
c = [1, 2]
d = [1, 2]
print(c is d)
print(c == d)
1.5、共享引用和在原位置修改
引用了一个在原位置上发生改变的对象,共享引用也同样改变。
list1 = [1, 2, 3, 4]
list2 = list1
print(list1)
print(list2)
list1 = "hello python" # 如直接给list1赋新值,则list2不变
print(list1)
print(list2)
如改变list2
所引用对象的一个元素,这类修改会在原位置上覆盖列表对象的某部分值。则list2
改变,尽管实质上并未改变list1
的值,list1
引用了一个在原位置上发生改变的对象,也同样改变。
list1 = [1, 2, 3, 4]
list2 = list1
print(list1)
print(list2)
# list1 = "hello python"
# print(list1)
# print(list2)
list2[2] = 100
print(list1)
print(list2)
1.6、使用Python复制而不是创建引用可以避免原位置修改问题
- 列表切片
# 列表切片
list1 = [1, 2, 3, 4]
list2 = list1[:]
print(list1)
print(list2)
list2[2] = 100
print(list1)
print(list2)
1.7、浅拷贝和深拷贝
浅拷贝
-
浅拷贝:copy函数可用于复制列表或字典等可变值,复制后的列表和原列表是两个独立的列表。
import copy list1 = [1,2,3] new_list = copy.copy(list1) new_list[0] = 0 print("old = ",list1) print("new = ",new_list)
深拷贝
-
深拷贝:如果要复制的列表中有列表,则使用
deepcopy()
函数完全复制。import copy list1 =[[1,2,3],['a','b','c']] new_list = copy.deepcopy(list1) #使用深copy. new_list[0][0] = 0 # 如果不使用deepcopy修改值不成功。 print("old = ",list1) print("new = ",new_list)
2. Python
常用的模块
2.1、模块的导入
库、包、模块的关系
-
模块:就是一个
.py
的文件 -
包:就是包含了模块,还有一个名叫
__init__.py
的文件才叫包,否则就是文件夹,__init__.py
可以是空文件也可以有代码。包里可以有包也可以有模块,可以多级结构混杂。 -
库:具有相关功能的包和模块的合集。(
web
自动化用的是selenium
第三方库,接口自动化用的是requests
第三方库) -
一个模块只会被导入一次,不管你执行了多少次
import
。 -
导入方式:
-
import
模块 :import
后面一般能跟模块,在调用其函数/类/变量的时候,用模块名.函数/类/变量的形式 (比如,import random,random.函数、类、变量) -
import...as...
:导入并重命名 -
from...import...
:from
后面可以跟包名,也可以跟“包名.模块名”,import
后面跟模块名或者类名,推荐使用该方式导入 -
from...import...as
在模块名或者包名过长时,为了后面的程序编写,可以给其取别名Alt+Enter:可以快速导入
-
2.2、随机模块-random
random
模块,用于生成伪随机数,之所以称之为伪随机数,是因为真正意义上的随机数(或者随机事件)在某次产生过程中是按照实验过程中表现的分布概率随机产生的,其结果是不可预测的,是不可见的。
常用的方法:
方法 | 作用 |
---|---|
random.randint(起始整数, 结束整数) | 随机一个整数 |
random.choice(非空序列) | 从非空序列中,选取一个随机数 |
random.randrange(起始整数, 结束整数[,步长]) | 随机一个正整数 |
random.smaple(序列, k) | 从序列中选择k个随机且独立的元素, 返回一个列表; |
举例:
# 打印随机数字,猜数字游戏
import random
num = random.randrange(1,100) #随机一个1到100的正整数
print(num)
shuru = int(input("输入一个数字:"))
if shuru == num:
print("猜对了!")
else:
print("猜错了!")
# ===randint=====================
print(random.randint(1,100))
# ===choice======================
list_1 = [1,2,3,4,5,6,7,8]
print(random.choice(list_1))
# ===choices======================
list1 = [1,2,3,4,5]
list_weights = [0,0,0,1,0]
list_cum_weights = [1,1,1,1,1]
print(random.choices(population=list1, cum_weights=list_cum_weights,k=5))
"""
cum_weights=[1, 1, 1, 1, 1]
• 等价于 weights=[1, 0, 0, 0, 0]
• [1,1+0,1+0+0,1+0+0+0,1+0+0+0+0]
• 看懂了没,太反人类了。。
cum_weights=[1, 4, 4, 4, 4]
• 等价于 weights=[1, 3, 0, 0, 0]
• [1,1+3,1+3+0,1+3+0+0,1+3+0+0+0]
"""
print(random.sample([1, 2, 3, 4, 5], 3))
2.3、字符串模块-string
这是一个内置模块,我们必须在使用任何常量和类之前将其导入
常用的方法:
属性 | 作用 |
---|---|
string.ascii_letters | 英文字母的大小写 |
string.ascii_lowercase | 英文字母的小写 |
string.ascii_uppercase | 英文字母的大写 |
string.digits | 数字 |
举例:
# 随机模块和字符串模块结合使用
import random
import string
# 随机取六位字母,判断输入和随机的是否相等
letter1 = random.sample(string.ascii_letters,6)
str1 = "".join(letter1)
print(str1)
str2 = input("请输入六位字母:")
if str2 == str1:
print("输入正确")
else:
print("输入错误")
2.4、os
模块
os
模块提供了多数操作系统的功能接口函数。当os
模块被导入后,它会自适应于不同的操作系统平台,根据不同的平台进行相应的操作,在python
编程时,经常和文件、目录打交道,这时就需要使用os
模块。
os
模块的常用函数
函数/属性 | 作用 |
---|---|
os.system("终端命令") | 执行终端命令 |
os.name | 操作系统的类型,nt表示windows,posix表示linux |
os.uname() | 返回操作系统的版本信息,包括操作系统的名称、内核版本、硬件信息等,注意这个方法只在linux 环境上支持 |
os.getcwd() | 返回当前工作的目录,相当于linux上的pwd命令 |
os.getenv(”path“) | 返回环境变量path的值 |
os.path.dirname("路径") | 返回指定文件的文件的父级目录 |
os.path.isdir("路径") | 判断文件夹是否存在,返回布尔值 |
os.path.isfile("路径") | 判断文件是否存在,返回布尔 |
os.path.exists("路径") | 即可判断文件夹也可以判断文件是否存在,返回布尔 |
os.path.jion("路径1", "路径2") | 实现两个路径的拼接 |
os.mkdir("路径") | 创建目录,相当于linux的mkdir命令 |
os.rmdir("路径") | 删除目录,只能删除空目录 |
os.listdir("路径") | 查询路径中的所有目录,括号里传路径 |
os.path.getatime("路径") | 返回当前路径的文件最后访问的时间/ 纪元时间 |
os.path.getmtime("路径") | 返回当前路径的文件最后修改的时间/ 纪元时间 |
os.path.getctime("路径") | 返回当前路径的文件创建的时间/ 纪元时间 |
查看当前系统的信息可以使用sys模块下
paltform
属性:print(sys.platform) # 当前系统的版本
获取当前文件的路径:
__file__
print(__file__) # D:/Document/PythonDoc/first_python/xxxx/file_demo.py
print(os.getenv("PATH"))
#判断C盘下是否存在一个名叫Python的文件夹?
os.path.isdir() #
os.path.isfile() #判断文件是否存在
os.path.exists() #既可以判断文件也可以判断文件夹
os.lisdir(路径) #获取盘下所有文件和目录名称
os.name #打印环境的操作系统
os.getpid() #打印运行id
os.getcwd() #求当前文件的路径
os.path.join() #路径拼接
def get_file(path, dir_list=[]):
"""
获取所有的文件
:param path:路径
:param dir_list:存放路径下所有的文件
:return:列表
"""
files = os.listdir(path)
for file in files:
file_path = os.path.join(path, file)
# 判断路径是否为文件,如果为文件,将文件追加到列表中
if os.path.isfile(file_path):
dir_list.append(file_path)
# 判断路径是否为目录,如果为目录,调用函数本身,将目录中的文件取出
else:
get_file(file_path, dir_list)
return dir_list
2.5、time
模块
time
模块提供各种与时间相关的函数,time
模块是Python
自带的模块。
2.5.1、Python
中的四种格式的时间:
-
纪元时间
epoch
格式时间:以秒为单位进行换算所得到的的时间,指的是从计算机时间元年1970.1.1
到现在所创建的时间之间的数转换成秒单位的浮点数,比如1630120707.7790058
; -
时间元组
struct-time
时间:比如time.struct_time(tm_year=2021, tm_mon=8, tm_mday=28, tm_hour=3, tm_min=18, tm_sec=58, tm_wday=5, tm_yday=240, tm_isdst=0)
; -
python
定义的英文格式显示时间:比如Wed Oct 16 09:49:02 2019
; -
自定义格式时间:按自己需要的格式来表示,比如
2021/8/20 11:20:20
。
2.5.2、time
模块中的常用函数
-
获取系统的当前时间:
time.time()
:返回当前时间,显示epoch
格式时间time.localtime()
:返回当前时间,显示struct-time
时间time.asctime()
:返回当前时间,显式英语格式time.gmtime()
:返回当前的格林威治时间
-
时间格式的转换:
-
time.gmtime()
:传入一个epoch
时间,转成时间元组格式,如果不传入参数则表示转换当前时间; -
time.mktime()
:作用和time.gmtime()
相反,以元组的形式传值,必须为9个值; -
time.strftime()
:传入一个自定义的格式和struct-time
格式的时间,把struct-time
格式的时间转成自定义的格式;%y 两位数的年份表示(00-99) %Y 四位数的年份表示(000-9999) %m 月份(01-12) %d 月内中的一天(0-31) %H 24小时制小时数(0-23) %I 12小时制小时数(0-12) %M 分钟数(0-59) %S 秒(00-59) %a 本地简化星期名称 %A 本地完整星期名称 %b 本地简化的月份名称 %B 本地完整的月份名称 %c 本地相应的日期表示和时间表示(e.g Thu Dec 10 09:54:27 2020) %j 年内的一天(001-366) %p 本地A.M.或P.M.的等价符 %U 一年中的星期数(00-53)星期天为星期的开始 %w 星期(0-6),星期天为星期的开始 %W 一年中的星期数(00-53)星期一为星期的开始 %x 本地相应的日期表示(e.g 12/10/20) %X 本地相应的时间表示(e.g 09:58:15) %Z 当前时区的名称(e.g 中国标准时间) %% %号本身
-
-
time.sleep(x)
:表示程序执行到这一行就休眠x秒,经常用在自动化代码中实现等待的效果。
print(time.strftime("%y年%m月%d日 %H:%M:%S", time.gmtime(os.path.getatime(r"D:\Document"))))
2.6、I/O
流操作
文件I/O
流指输入输出操作(input、output)
-
open
函数 -
打开文件的模式(
mode
的值,默认为r)r
: 以只读方式打开文件r+
: 打开一个文件用于读写(会在已有的内容前且会覆盖原有的前面的内容添加数据)w
: 打开一个文件只用于写入(不存在则创建,存在则完全覆盖内容)w+
: 打开一个文件用于读写(覆盖已有的数据)a
:打开一个文件用于追加(不存在则创建,存在就在文件最后追加内容)a+
:打开一个文件用于读写(追加数据)b
:二进制打开文件(打开图片、视频等)
2.6.1、创建文件
# mode为“w”时,如果有这个文件,就直接打开,如果没有则新建一个再打开
file_1 = open('d:xiao.txt',mode='w')
# 操作完成后关闭文件
file_1.close()
2.6.2、读取一个文件存入到另外一个文件
# 读取文件内容,写入另一个文件
# 打开文件
f1 = open(r"d:\test.txt")
# 读取内容
data = f1.read()
#创建文件,mode=a或w,如果文件不存在就会先创建再写入a表示追加,w表示覆盖
f2 = open(r"d:\test2.txt",mode="a")
#写入内容
f2.write(data)
# 关闭文件
f1.close
f2.close
2.6.3、with open as
结构
我们都知道打开文件方式使用open
函数,再对文件操作完成后需要调用close
方法来关闭文件。有时候回存在打开和关闭异常,为了避免异常的存在我们一般使用with open("文件路径", mode="模式") as fp
方式来打开文件。
# 无论中间代码执行是否错误,最后都会关闭文件
with open(r"d:\test.txt",mode='r') as f1:
print(f1.read())
2.6.4、 open
和with open as
的区别
- open()函数:这样直接打开文件,如果出现异常,如读取过程中文件不存在或异常,则直接出现错误,close方法无法执行,导致文件无法关闭。
- 用with语句的好处,就是到达语句末尾时,即便出现异常也会自动关闭文件
2.7、Excel
的操作模块-openpyxl
前面讲的模块都属于Python内置的模块,使用前不需要安装,直接导入即可;这里的openpyxl
属于第三方模块,在使用前必须先安装。
openpyxl
是读写excel
文件的第三方库
安装方式:
-
pip install openpyxl
-
在
pycharm
中安装
在使用openpyxl
模块之前,需要先搞清楚以下两个概念:
workbook
:工作簿,即整个excel
文件worksheet
:工作表,一个excel
文件中可以有多个工作表
2.7.1、新建Excel文件进行读写操作
#导入Workbook类
from openpyxl import Workbook
#实例化Workbook对象,相当于新建了一个excel文件
wb = Workbook()
#获取活动的工作表
ws = wb.active
#指定单元格写入内容
ws["A6"] = "蓉华教育"
#列表中写入一行数据
list1 = [1,3,45,6]
ws.append(list1)
#列表中的嵌套列表中的数据导入
data = [[11,22,33],[44,55,66],[77,88]]
for i in data:
ws.append(i)
#新建一个名叫“名单”的sheet页,并且把它放到第一个位置
ws_2 = wb.create_sheet("名单",0)
#操作名单的sheet页面
#保存文件
wb.save(r"c:\test01.xlsx")
2.7.2、打开已有的Excel
文件进行读写操作
### 找指定单元格的数据
import openpyxl
# 打开文件
wb = openpyxl.load_workbook(r"test01.xlsx")
# 选择sheet页
ws = wb["Sheet"] # 新方法,和下面老方法一样
# ws=wb.get_sheet_by_name("Sheet") # 老方法,逐步要淘汰了
#获取单元格对象
cell = ws["A3"]
# 打印单个单元格的列,行,值
print(cell.column,cell.row,cell.value)
# 打印单元格的坐标和值
print(cell.coordinate,cell.value)
#获取excel列的数量
print(ws.max_column)
#获取行列的数量
print(ws.max_row)
2.7.3、打开txt
文件,读取内容写入excel
(批量写入)
eval()
函数使用实例:
字符串转换成其他数据类型:"[]“转换出来列表,如果”()"转换出来为元组,如果为“{}”转换出来为字典
a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
b = eval(a)
print(b)
输出为:[[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]
type(b)
输出为:list
a = "{1: 'a', 2: 'b'}"
b = eval(a)
print(b)
输出为:{1: 'a', 2: 'b'}
type(b)
输出为:dict
a = "([1,2], [3,4], [5,6], [7,8], (9,0))"
b = eval(a)
print(b)
输出为:([1, 2], [3, 4], [5, 6], [7, 8], (9, 0))
#打开文件
with open(r"d:\list1.txt") as fi:
#读取文件内容
data = fi.read()
#将字符串转换为列表
list01 = eval(data)
for i in list01:
ws.append(i)
wb.save(r"d:\test02.xlsx")
2.7.4、从文件excel中读取数据
### 找指定单元格的数据
import openpyxl
# 打开文件
wb = openpyxl.load_workbook(r"d:\test02.xlsx")
# 选择sheet页
ws = wb["信息"]
li = ws["a3"]
# 打印单个单元格的列,行,值
print(li.column,li.row,li.value)
# 打印单元格的坐标和值
print(li.coordinate,li.value)
### 批量读取excel中的数据
ws = wb["信息"]
#第一个for循环读取的为一行的数据
for i in ws:
# 第二个for循环读取的为单个
for cell in i:
print(li1.coordinate,li1.value)
# 读取excel中的文件并以列表格式展示
import openpyxl
# 打开文件
wb = openpyxl.load_workbook(r"d:\test02.xlsx")
ws = wb["信息"]
# 取出来的数据用[[],[],[]]格式展示
all_list =[]
#第一个for循环读取的为一行的数据
for i in ws:
list1 = []
# 第二个for循环读取的为单个
for j in i:
j.append(li1.value)
all_list.append(list1)
# 打印不要表头数据
print(all_list[1::])
2.8、MySQL
数据库的操作-pymysql
在做测试过程中,我们可以把测试数据创建在数据库,也可以读取数据库中的数据进行断言操作
python操作数据库之前需要安装数据库驱动
- 安装方式:
pip install pymysql
连接并操作数据库
import pymysql
# 连接数据库
my_connect = pymysql.connect(host = '',user = '',password = '',database = '',port = ,charset = 'utf8')
# 建立游标:目的是为了缓存数据方便操作(读取数据,遍历表中的所有数据,以便查询)
du_shuju = my_connect.cursor()
#执行sql语句
du_shuju.execute("select * from xxxxx;")
#获取数据
huoqu_data = du_shuju.fetchall()
print(huoqu_data)
#修改表中的数据
du_shuju.execute("update 表名 set 字段名="xxx" where 字段名="yyy";")
#提交数据,修改的数据要进行提交才能修改数据库中的数据,否则修改的只是游标缓存里的数据
my_connect.commit()
注意点:链接数据库的connect
类返回的是链接对象,使用链接对象创建游标对象。使用游标对象的execute
方法执行sql
语句。如果是更新表操作需要使用链接对象commit
提交。如果是查询操作需要使用游标的对象的fetchall
方法获取查询结果,不需要使用链接对象commit
提交,因为查询操作没有更新表。
注意点:如果查询操作获取返回结果,使用游标对象的
fetchall
方法获取。
fetchall
方法是临时的,注意需要使用变量结束fetchall
方法的返回结果。
2.9、ini
文件的操作-configparser
什么是ini
文件
ini
文件是Initialization File
的缩写,即初始化文件,是windows
的系统配置文件所采用的存储格式。
ini
文件的格式:ini
文件由节、键、值组成。
[节点/section]
(键=值)
key=value
例子:setup.ini
[Startup]
RequireOS=Windows 7
RequireMSI=3.1
RequireIE=7.0.0000.0
Require64BitVCRT=1
[Windows 7]
PlatformID=2
MajorVersion=6
MinorVersion=1
模块-configparser
configparser
是第三方模块,主要是用来操作ini
文件
安装方式:pip install configparser
读取ini
文件中的内容
使用configparser的Configparser类是实例对象的read
方法读取ini
文件,需要给read
传入ini
文件路径。
# 注意点:Configparser类的实例对象的read方法的机制:读取ini文件之后加载到Configparser类的实例对象中的。
# 1:获取ini文件的绝对路径 os.path.dirname(os.path.dirname(__file__))获取当前文件父级的父级目录
ini_path = os.path.dirname(os.path.dirname(__file__)) + '/data_config/config.ini'
# 2: 创建Configparser类的实例对象
conf = configparser.ConfigParser()
# 3: 调用read方法读取ini文件
# read("ini文件的路径"):返回值是读取成功的文件路径。机制:讲读取成功的文件加载到Configparser类型的实例对象中
conf.read(ini_path)
获取指定建的值
使用configparser的Configparser类是实例对象的get
方法获取ini
文件下指点键对应的值。
conf = configparser.COnfigparser()
conf.get("节点名", "键")
2.10、json
文件操作-json
json
是用来存储简单的数据结构和对象的文件。json
是一种轻量级的数据交换格式,基于ECMAScript
(欧洲计算机协会制定的js
规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据,用于许多Web应用程序来进行数据交换。
json
文件的格式或者json
数据的格式
1.列表方式 [ ]---列表套字典或者列表套列表
[{
"id" : 1 ,
"name" : "xiaoming"
},{
"id" : 2 ,
"name" : "xiaohong"
},["name", "age", "sex"]
]
2.字典方式 { }--字典套字典或者字典套列表
// 前后端分离,推荐后端返回给前端数据格式
{
"status" : 0 , //执行状态码
"msg" : "SUCCESS", //说明文字信息,没有为NULL
"data" :[{ //对象中嵌套数组,数组是返回的数据,
"id" : 1 ,
"name" : "xiaohong"
},{
"id" : 2,
"name" : "xiaoming"
}]
}
3.反例
{"id" : ox16 } //不合法,数值需要是十进制
{"name" : underfined } //不合法,没有该值
[{
"name" : NUll,
"school" : function() {
console.log("该写法是错误的")
}//不合法
}]//json中不能使用自定义函数,或系统内置函数
json
模块是python自带的
json.load/json.loads
-
json.load(文件对象)
:将json
文件转成python
对象 -
json.loads(字符串)
将字符串数据转成python
对象# json.laods(字符串) json_data = '{"a": {"b": {"c": "数据"}}}' result = json.loads(json_data) print(type(result)) # json.load(文件对象) with open(r'json文件路径', mode="r") as f: print(json.load(f))
json.dump/json.dumps
-
json.dump(obj, fp)
:将python
对象写入json
文件 -
json.dumps(obj)
:将python
对象转成json
数据# json.dumps(obj) dict1 = {"a": {"b": {"c": "数据"}}} result = json.dumps(dict1) print(type(result)) # json.dump(obj, fp) dict2 = {"a": {"b": {"c": "数据"}}} with open(r"json_data.json", mode="w") as fp: json.dump(dict2, fp)
2.11、yaml
文件操作-pyyaml
yaml
文件的应用场景
yaml其实也类似于 json、txt ,它们都属于一种文本格式。在我们的实际工作中, yaml 文件经常作为服务期配置文件来使用。 比如一些定义好的内容,并且不会修改的信息,我们就可以通过定义 yaml 文件,然后通过读取这样的文件,将数据导入到我们的服务中进行使用。
由于 yaml
文件一般作为配置文件使用,所以较少会修改。
yaml
文件的格式
1、大小写敏感
2、使用缩进表示层级关系
3、缩进的空格数目不重要,只要相同层级的元素左侧对齐即可,通常开头缩进两个空格
4、不支持Tab键制表符缩进,只使用空格缩进
5、字符后缩进一个空格,如冒号,逗号,短横杆(-)等
6、"—“表示YAML
格式,一个文件的开始,用于分隔文件间
7、”#”表示注释 (yaml
文件只有行注释)
YAML 支持的数据结构有三种。
-
对象:键值对的集合,又称为字典(dictionary)
-
数组:一组按次序排列的值,又称为 列表(list)
-
纯量(scalars):单个的、不可再分的值
下面对这三种数据结构做详细介绍:
yaml 中的值有以下基本类型:
-
字符串
-
整形
-
浮点型
-
布尔型
-
null
-
时间
-
日期
# 注释 # 1-1、字典 键: 值 username: xiaoming # 冒号后面是空格 password: 123456 info: 配置 # 中文---不建议使用,有可能会乱码 # 1-2、字典嵌套 NAME_PSW: name: xiaoming password: 123456 # 字典套列表 person: name: 锋声 age: 18 man: true address: - 深圳 - 北京 - 广州 # 字典套列表 person1: name: 锋声 age: 18 man: true address: [深圳, 北京, 广州] # 字典套列表 childs: - name: 锋声 age: 10 - name: 锋声 age: 15 # 字典套列表 person2: name: 锋声 age: 18 man: true address: [深圳, 北京, 广州] twoArr: - - 2 - 3 - 1 - - 10 - 12 - 30 # 列表 - 1 - 2 # 列表嵌套字典 - user1: aaa - user2: bbb age: 10 sex: male
第三方包 - pyyaml
pyyaml
的安装:pip install PyYAML
import yaml
def read(path):
with open(path, 'r') as file:
data = file.read()
result = yaml.load(data)
# result = yaml.load(data, Loader=yaml.FullLoader)
return result
这是因为在 YAML 5.1
版本后弃用了yaml.load(file)
这个用法,因为觉得很不安全,5.1版本之后就修改了需要指定Loader
,通过默认加载器(FullLoader)
禁止执行任意函数,该load
函数也变得更加安全。所以我们需要将 result = yaml.load(data)
改为 result = yaml.load(data, Loader=yaml.FullLoader)
。
解决该 TypeError
不单单 只有 yaml.load(data, Loader=yaml.FullLoader)
这一个方法。
以下三选一即可解决该 TypeError
yaml.safe_load(file.read())
yaml.load(file.read(), Loader=yaml.FullLoader)
yaml.load(file.read(), Loader=yaml.CLoader)
2.12、sys
模块
sys模块是与python解释器交互的一个接口。sys 模块提供了许多函数和变量来处理 Python 运行时环境的不同部分。
2.12.1 处理命令行参数–sys.argv
在解释器启动后, argv
列表包含了传递给脚本的所有参数, 列表的第一个元素为脚本自身的名称。
2.12.2 退出程序,正常退出时exit(0)
–sys.exit(n)
sys.exit(5)
print(11)
print(11)
print(11)
# 退出python执行程序,下面的代码将不会执行,如同shell中的exit一样。
2.12.3 获取Python解释程序的版本信息
import sys
print(sys.version)
2.12.4 操作系统平台名称
import sys
print(sys.platform)
3. 异常处理
认识错误(BUG)
关于错误
- 编写的程序不能正常执行,或者执行的结果不是我们期望的
- 俗称
BUG
,是程序员在开发时非常常见的,初学者常见错误的原因包括:- 手误
- 对已经学习过的知识理解还存在不足
- 对语言还有需要学习和提升的内容
- 在学习语言时,不仅要学会语言的语法,而且还要学会如何认识错误和解决错误的方法
每一个程序员都是在不断地修改错误中成长的
第一个演练中的常见错误
- 1> 手误,例如使用
pirnt("Hello world")
NameError: name 'pirnt' is not defined
名称错误:'pirnt' 名字没有定义
- 2> 将多条
print
写在一行
SyntaxError: invalid syntax
语法错误:语法无效
每行代码负责完成一个动作
- 3> 缩进错误
IndentationError: unexpected indent
缩进错误:不期望出现的缩进
- Python 是一个格式非常严格的程序设计语言
- 目前而言,大家记住每行代码前面都不要增加空格
- 4>
python 2.x
默认不支持中文
目前市场上有两个 Python 的版本并存着,分别是 Python 2.x
和 Python 3.x
Python 2.x
默认不支持中文Python 3.x
默认支持中文Python 2.x
的解释器名称是python
需要在安装python2
的目录把python.exe
文件更改为python2.exe
Python 3.x
的解释器名称是python
SyntaxError: Non-ASCII character '\xe4' in file 01-HelloPython.py on line 3,
but no encoding declared;
see http://python.org/dev/peps/pep-0263/ for details
语法错误: 在 01-HelloPython.py 中第 3 行出现了非 ASCII 字符 '\xe4',但是没有声明文件编码
请访问 http://python.org/dev/peps/pep-0263/ 了解详细信息
ASCII
字符只包含256
个字符,不支持中文
异常
- 异常是指事件会在程序执行过程中发生错误,影响了程序的正常执行
- 一般情况下,在
python
无法正常处理程序时就会发生一个异常,即报出错误 - 当
python
脚本发生异常时我们需要捕获处理它,否则程序会终止执行
try语句
try里面一般放你觉得可能会出错的代码
3.1、格式一:try……except
-
自动引发异常(常用),在自动化时,可以用来写日志,将报错写入日志中,方便查看问题。
input_str = input('请输入一个数字:') try: print('输入内容是%d'%input_str) except TypeError: # 自动引发异常 raise TypeError('请输入数据类型的正确数字!')
3.2、格式二:try:… finally:…
-
try:… finally:… :先运行try,然后再运行finally,不管try里面代码运行是否失败
try: print("进入try") file = open(r'd:\test.txt',mode='r') print("已经打开了文件") finally: file.close() print('结束')
3.3、格式三:try:……except……finally:……
-
不管try执行是否正常,都会执行finally,只有异常才会执行except
try: print("进入try") file = open(r't.txt',mode='r') print("已经打开了文件") except Exception as e: print('进入except') print('报错信息:',e) finally: print('结束')
3.4、格式四:try:…except:……
-
当try运行正常不执行except,当try运行不正常,运行except。
try: print("进入try") file = open(r'd:\test7.txt',mode='r') print(file.read()) print("已经打开了文件") except Exception as e: print('进入except') print('报错信息:',e) #Exception是常规错误的基类;BaseException是所有异常的基类。
3.5、格式五:try:…except:…else:……
-
try: … except: …else :……当try代码正常,则不执行except的代码,但是要执行else的代码;反之要执行except,而不执行else
try: print("进入try") file = open(r'd:\test08.txt',mode='r') print("已经打开了文件") except Exception as e: print('进入except') print('报错信息:',e) else: print("其它") finally: print("最终的") #捕获多个异常举例 try: 1/0 except IndexError: print("异常1") except ZeroDivisionError: print("除数不能为0") else: print("没有异常") finally: print("有没有异常都要执行")