异常处理
#
#一个标准的try except语句,至少要有一个except,也可以有多个except,也可以加一个else语句,以及finally语句
try:
int1=int(input('请输入一个整数'))
print(1/int1)
except ZeroDivisionError:
print('0不能作为分母')
except ValueError:
print('您输入的不是整数')
except: #以上的异常没有捕捉到的情况下,此处起到兜底的作用
print('程序有问题')
else: #程序未出现异常,则执行else中的语句
print('没有出现异常')
finally: #无论程序是否出现异常,都会执行
print('程序运行完毕')
#常见的异常
# NameError #未定义的变量
# print(num1)
# IndexError
# list1=[10,20]
# print(list1[2])
# IOError #输入输出异常
# FileNotFoundError
with open('D:/中国足球勇夺世界杯冠军.txt') as file1:
file1.read()
#所有的异常,都是Exception的子类或者子类的子类
print(NameError.__bases__)
print(IndexError.__bases__)
print(LookupError.__bases__)
#Exception也有一个父类,BaseException
print(Exception.__bases__)
print(BaseException.__bases__)
#手动抛出异常
try:
raise IOError #假装这里有异常
except:
print('文件读写错误')
#日志模块
import time #加载时间模块
import logging #加载日志模块
import traceback #加载配合日志的异常模块
logging.basicConfig(level='DEBUG',filename='D:/log_210315.log',filemode='a+')
logging.debug('这是debug级信息')
logging.info('这是info级信息')
logging.warning('这是warning级信息')
logging.error('这是error级信息')
logging.critical('这是critical级信息')
try:
int1=int(input('请输入一个整数'))
print(1/int1)
except ZeroDivisionError:
logging.error(time.strftime('%y-%m-%d %H:%M:%S')+traceback.format_exc())
except ValueError:
logging.error(time.strftime('%y-%m-%d %H:%M:%S')+traceback.format_exc())
except: #以上的异常没有捕捉到的情况下,此处起到兜底的作用
print('程序有问题')
else: #程序未出现异常,则执行else中的语句
logging.info('服务器未出现异常')
finally: #无论程序是否出现异常,都会执行
print('程序运行完毕')
#课堂小结
#try,excpet,else,finally
#常见的异常
#所有的异常都是Exception的子类
#手动抛出异常 raise
#将异常写入日志
第9次课思考题讲解
#解题思路
#1.建立一个老虎的类
#2.建立一个羊的类
#3.建立一个房间的类
#4.把老虎或者羊放入房间
#5.写游戏相关的代码
class Tiger:
def __init__(self):
self.name='老虎'
self.weight=200
def eat(self,food):
if food=='meat':
print('喂食正确')
self.weight+=10
elif food=='grass':
print('喂食错误')
self.weight-=10
def roar(self):
print('Wow!')
self.weight-=5
class Sheep:
def __init__(self):
self.name='羊'
self.weight=100
def eat(self,food):
if food=='grass':
print('喂食正确')
self.weight+=10
elif food=='meat':
print('喂食错误')
self.weight-=10
def roar(self):
print('mie~')
self.weight-=5
#建立一个房间的类
class Room:
def __init__(self,category):
self.category=category
roomlist=[] #定义一个列表,等下用来存放房间的实例
from random import randint
for i in range(10):
if randint(1,2)==1: #相当于扔硬币决定是生成老虎还是生成羊
category=Tiger() #实例化一个老虎
else:
category=Sheep() #实例化一个羊
rm=Room(category) #实例化一个房间,里面有一个动物
roomlist.append(rm) #把房间的实例放到列表中
import time
start_time=time.time() #记录游戏开始时间
while time.time()-start_time<=10:
room_number=randint(0,9) #随机选择一个数字作为房间号
random_room=roomlist[room_number] #选取该房间
load1=input(f'当前访问的是{room_number+1}号房间,请问是敲门还是喂食?1/2')
if load1=='1':
random_room.category.roar() #调用房间中的动物的叫的方法
elif load1=='2':
food=input('请输入需要喂的食物 meat/grass')
if food=='meat' or food=='grass':
random_room.category.eat(food) #调用房间中的动物的吃的方法
else:
print('您输入的食物不正确')
else:
print('您输入的操作不正确')
else:
print('游戏时间到')
for i in range(len(roomlist)):
print(f'{i+1}号房间的动物是{roomlist[i].category.name},体重是{roomlist[i].category.weight}')
正则表达式
#正则表达式,其实就是从一段字符串中提取出需要的字符
import re #加载正则表达式模块
re.findall(参数1,参数2,参数3) 参数1表示用什么规则进行提取,参数2表示从哪个字符串进行提取
#参数3一般有re.I 表示不区分大小写,re.S 匹配多行中满足条件的值
str1='abcdefg'
#. 通配符,匹配某个字符前面或后面的一个字符
print(re.findall('a.',str1)) #提取a后面的一个字符,返回值是列表,包括条件a也返回
print(re.findall('a(.)',str1)) #提取a后面的一个字符,返回值是列表,不包括条件a
#* 通配符,匹配某个字符后面的若干个字符,若干也包括0个的情况
str1_1='abcdabbcbbbbeafg'
print(re.findall('ab*',str1_1)) #把所有a后面有若干个b的字符找出来,包括0个b的情况
#? 通配符,匹配某个字符串后面有0-1个字符
str1_2='abacabbbbbd'
print(re.findall('ab?',str1_2))
#+ 通配符,匹配某个字符串后面有一个或多个字符,不包括0个的情况
print(re.findall('ab+',str1_2))
#.*? 提取字符串两端之间的内容 A(.*?)B
load1='一二三四五六七八九'
print(re.findall('三(.*?)六',load1))
#如果只有一端给出了条件,值会怎么取?
print(re.findall('三(.*?)六',load1)) #懒惰匹配,在符合查询要求的情况下,尽可能少的匹配
print(re.findall('(.*?)六',load1)) #需要匹配的字符串后面是'六',无法偷懒
#只给出一端的条件时,如果希望获取后面全部的结果,则应当使用贪婪匹配
print(re.findall('三(.*)六',load1)) #贪婪匹配
#当有多个满足条件的值时,两者的结果并不相同
load1='一二六三四五六三七八九六'
print(re.findall('三(.*?)六',load1)) #懒惰匹配
print(re.findall('三(.*)六',load1)) #贪婪匹配
#如果没有满足条件的查询,返回空列表
print(re.findall('九(.*?)一',load1)) #懒惰匹配
print(re.findall('九(.*)一',load1)) #贪婪匹配
#\w{n} 匹配字母,数字,下划线,n表示连续满足条件的位数
str3='nyrbt'
print(re.findall('\w{3}',str3))
#\W 匹配\w的补集
str3_new='ny#$%rbt'
print(re.findall('\W{3}',str3_new))
#\s 匹配空格,换行符\n,制表符\t
str6='''小娃撑小艇,
偷采白莲 回.
不解藏踪 迹,
浮萍一道 开
'''
print(re.findall('\s',str6))
#\S \s的补集
print(re.findall('\S',str6))
#^匹配开头,$匹配结尾
list1=['abcde','deabc','fabcf']
for one in list1:
if re.findall('^abc',one): #匹配以abc开头的字符串
print(one,'以abc开头')
elif re.findall('abc$',one): #匹配以abc结尾的字符串
print(one,'以abc结尾')
#re.I 不区分大小写
req='AbcabcABcaBCabCABC'
print(re.findall('abc',req,re.I))
#re.S 匹配多行中符合条件的值
req2='''hellounyrbtyutnhbgumynhbg
,imyuntbuimyuntybr
68,imyuntybrytnuymi,oumworld'''
print(re.findall('hello(.*?)world',req2,re.S))
#课堂小结
#正则表达式的通配符 . * ? +
#加()和不加()的区别
#.*? 懒惰匹配 .* 贪婪匹配
#\w,\s
#re.I,re.S
网络爬虫
import re
import requests
url='https://www.xs4.cc/chapter/?870.html' #需要爬取的网址
req=requests.get(url)
req.encoding='gbk' #将编码转为gbk格式
book_name=re.findall('<h1>(.*?)</h1>',req.text)[0] #取得书名
mulu=re.findall('title="(第.*?)">第',req.text) #取得所有章节的目录
# for i in range(1,len(mulu)):
# print(mulu[i])
wangzhi=re.findall('<a href="article(.*?).html"',req.text) #取得所有章节的正文网址
# for i in range(1,len(wangzhi)):
# print(f'https://www.xs4.cc/article{wangzhi[i]}.html')
dict1={}
for i in range(1,len(mulu)):
dict1[mulu[i]]=f'https://www.xs4.cc/article{wangzhi[i+1]}.html'
for k,v in dict1.items():
print(k,v)
爬取全书网正文
import re
import os
import requests
import xlwt,xlrd
url='https://www.qzguermei.com/d/1020/'
req=requests.get(url)
name=re.findall('<h1>(.*?)</h1>',req.text)[0] #取得书名
mulu=re.findall('html" title="(.*?)" target="_blank"',req.text) #获取目录
wangzhi=re.findall('<a href="/d/1020/(.*?).html" title="',req.text) #获取网址
dict1={}
for i in range(14,len(mulu)):
dict1[mulu[i]]=f'{url}{wangzhi[i]}.html'
#写入文件
excel1=xlwt.Workbook() #实例化一个excel
worksheet=excel1.add_sheet(f'{name}') #新建一个sheet
worksheet.write(0,0,'目录') #行,列,值
worksheet.write(0,1,'网址') #行,列,值
row=1
for k,v in dict1.items():
worksheet.write(row,0,k) #将目录写入到excel
worksheet.write(row,1,v) #将网址写入到excel
row+=1
excel1.save(f'd:/{name}.xls')
#读取excel
data=xlrd.open_workbook(f'd:/{name}.xls') #读取一个excel文件
sheet1=data.sheets()[0] #读取第一个sheet
for i in range(1,sheet1.nrows): #nrows 返回有效行数
print(sheet1.cell_value(i,0),sheet1.cell_value(i,1))
#获取正文内容
if not os.path.exists(f'd:/{name}'): #判断目录是否存在,如果不存在,则
os.mkdir(f'd:/{name}') #新建一个以书名命名的目录
count=1
for k,v in dict1.items():
if count>=5:
break
else:
zhengwen=requests.get(v) #获取正文网页的内容
neirong=re.findall('id="chaptercontent">(.*?)全书网手机阅读地址',zhengwen.text,re.S)[0] #获取正文内容
neirong=neirong.replace(' ','').replace('<br/><br/>','\n') #去掉多余的字符
with open(f'd:/{name}/{count:04}_{k}.txt','w+') as file1:
file1.write(neirong)
count+=1
#阶乘
# 6!=6*5!
# 5!=5*4*3*2*1
#
# n!=n*(n-1)!
#递归
def jiecheng(n):
if n==1:
return 1
else:
return n*jiecheng(n-1)
print(jiecheng(6))
pytest
#pytest是一种自动化测试框架,是python的第三方单元测试框架,向下兼容unittest
#预期结果,实际结果
pip install pytest,或者使用豆瓣源,清华源等进行安装
#pytest命名规范
#文件名应当以test_开头,或者以_test结尾
#类应当以Test开头,且类当中不能有__init__方法
#方法或函数应当以test_开头
#断言必须使用assert 结果为真,断言不做事情,结果为假,断言生效,抛出异常AssertionError
assert 1==2 #判断等式两边是否相等
assert 200 #判断某个语句是否为真
assert 10 in [10,20] #判断某个值是否属于某个对象
assert 1!=2 #判断某个值是否不等于另一个值
assert not False
import pytest
import allure
import os #加载系统模块
def test_01():
print('HelloWorld')
assert 1==1 #判断预期结果和实际结果是否一致
def test_02():
assert 1==2
class Test1:
def teardown_method(self): #④
print('这是最后执行的方法')
def test_c01(self): #②
assert 10==100
def test_c02(self): # ③
assert 1 == 1
def setup_method(self): #①
print('这是最先执行的方法')
#method级别 ①②④①③④
# class Test1:
def teardown_class(self): #④
print('这是最后执行的方法')
def test_c01(self): #②
assert 10==100
def test_c02(self): # ③
assert 1 == 1
def setup_class(self): #①
print('这是最先执行的方法')
#class级别 ①②③④
class Test10:
@pytest.mark.parametrize('result,real_result',[[3,6],[6,9],[18,18]]) #数据驱动,参数化
def test_10(self,result,real_result):
assert result==real_result
@allure.feature('层级1')
@allure.story('层级2')
@allure.title('层级3')
class Test20:
def test_20(self):
assert 3+6==9
#pytest框架,测试通过,显示".",测试不通过,显示F
if __name__ == '__main__':
pytest.main(['test_pytest210319.py','-s','--alluredir','./report']) #test_pytest210319.py 文件名 -s展示打印的语句
os.system('allure generate ./report -o ./report/report --clean')
#课堂小结
#pytest框架的概念,命名规范
#assert断言
#pytest的写法
#setup,teardown,@pytest.fixture(scope='class')
#数据驱动 @pytest.mark.parametrize
#allure环境搭建
# 1、下载allure.zip
# 2、解压allure.zip到一个文件目录中
# 3、将allure报告安装目录\bin所在的路径添加环境变量path中
# 4、pip install allure-pytest
# 5、验证
fixture
#test_example1
import pytest
@pytest.fixture(scope='class') #装饰器,相当于setup_method
# 缺省级别为function级,可以使用scope='class'更改级别
#scope='module'
#scope='session' 选择这个级别时,将fixture的内容写到conftest.py中,目录下的所有文件共用这个配置
def some_data():
print('开始')
yield #这句话以下的内容,视为teardown_method
print('结束')
def test_some_data(some_data):
print('test')
if __name__ == '__main__':
pytest.main(['test_example1.py','-s'])
#将九九乘法表写入文件
with open ('d:/九九乘法表_210319.txt','w+') as file1:
for i in range(1,10):
for j in range(1,i+1):
file1.write(f'{j}*{i}={i*j}\t')
file1.write('\n')
python知识点复习上
#单引号,双引号,三引号
str1="It's OK"
print(str1)
str2='He said:"Are you OK?"'
print(str2)
str3="""He said:"Are you OK?",It's OK"""
print(str3)
str3_new='''空山不见人
但闻人语响
返景入深林
复照青苔上'''
print(str3_new)
#字符串的拼接
print('A'+'B')
print('1'+'6')
print('1'*'6') #报错
print('1'*6)
#字符串的转换 int(),float(),str()
num1=3.6
num1_1='3.6'
print(int(num1))
print(int(float(num1_1))) #直接转'3.6'会报错,可以先转为float型的3.6,再转为int型
#转义符
path1='d:\note1.txt'
path1='d:\\note1.txt' #再加一个\去掉转义符的特殊含义
path1=r'd:\note1.txt' #字符串前面加一个r,表示后面的字符串不进行转义
path1='d:/note1.txt' #路径可以使用/代替\
#字符串的下标
str6='nybtevrc'
print(str6[5])
print(str6[-3])
str6[5]='c' #报错,字符串是不可变对象
#字符串的切片 [起始值:终止值:步长] 包含起始值,不包含终止值,步长默认为1
#字符串的切片是生成了新对象,与原对象无关
print(str6[3:6])
print(str6[-5:-2])
print(str6[5:2:-1]) #vet
print(str6[-3:-6:-1]) #vet
#翻转字符串
print(str6[::-1])
#列表可以存放哪些对象?任意对象
#列表是可变对象,可以增删改
#增 append,insert,extend
#改 通过下标就可以改
#删 pop,remove,del
#1,1,2,3,5,8,13,21,34 斐波那契数列
list1=[]
for i in range(20):
if i<=1:
list1.append(1)
else:
list1.append(list1[-2]+list1[-1])
print(list1)
#列表的切片,也是生成一个新的对象,原理与字符串的切片一样
print(list1[:]) #生成一个完整的切片,原列表的一个复制
#元组 元组也可以使用下标和切片,但是元组是不可变对象
tuple1=(10,) #元组中只有一个值时,后面加一个逗号
print(type(tuple1))
tuple2=(10,20,30)
print(tuple2[:2])
#浅拷贝,深拷贝
list9=[10,20,30,[40,50]]
list9_new=list9 #此处实际上只是建立了list9的一个快捷方式
list9[0]=200
print(list9)
print(list9_new)
import copy
list9_new=copy.copy(list9) #浅拷贝 列表是不同的对象,子列表仍然是相同的对象
list9[0]=200
list9[-1][0]=360 #对子列表修改,两者仍然指向的是同一个子列表
print(list9)
print(list9_new)
#浅拷贝等价于切片list9_new=copy.copy(list9),也可以写成list9_new=list9[:]
list9_new=copy.deepcopy(list9) #深拷贝,列表和子列表都是不同的对象
list9[-1][0]=360
print(list9)
print(list9_new)
#list()函数,将对象转为列表,tuple()函数,将对象转为元组
#布尔表达式
#and 一假为假,全真为真
#or 一真为真,全假为假
#210321_python知识点复习下
import time
for i in range(10,0,-1):
print(f'\r倒计时{i}秒',end='') #\r让光标回到行首
time.sleep(1) #让程序等1秒
else: #循环正常结束时,执行一次else中的语句
print(f'\r倒计时结束')
for i in range(1,11):
if i==5:
# break #终止循环
continue #跳出一次循环
else:
print(i)
#使用while循环时,注意设置终止条件,如果while后面的布尔表达式始终为真,则会变为死循环
i=0
while i<=5:
print('12345')
i+=1
#文件读写
with open('d:/210321.txt','w+') as file1:
file1.write('庆历四年春,滕子京谪守巴陵郡.')
file1.seek(0)
print(file1.read())
#字典
#字典是可变对象
#字典的键可以存放不可变对象
#字典的值可以存放任何对象
#字典以键值对的形式进行存放
#字典是无序的
dict1={'A':'apple','B':'book'}
dict2={'B':'book','A':'apple'}
# print(dict1==dict2)
for k,v in dict1.items():
print(k,v)
#json格式
str1='''{
"aac003" : "tom",
"tel" : "13959687639",
"crm003" : "1",
"crm004" : "1"
}'''
import json #加载json模块
str1_new=json.loads(str1) #loads()方法,将json格式转为真正的字典
# print(type(str1_new))
str2=json.dumps(str1_new) #dumps()方法,将字典转为json格式
print(type(str2))
print(str2)