Day06、Python概念:异常处理,测试,数值与日期

一、Python 异常处理

python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误。你可以使用该功能来调试python程序。

python标准异常

异常名称描述
BaseException解释器请求退出
KeyboardInterrupt用户中断执行(通常是输入^C)
Exception常规错误的基类
StopIteration迭代器没有更多的值
GeneratorExit生成器(generator)发生异常来通知退出
SystemExitPython 解释器请求退出
StandardError所有的内建标准异常的基类
ArithmeticError所有数值计算错误的基类
FloatingPointError浮点计算错误
OverflowError数值运算超出最大限制
ZeroDivisionError除(或取模)零 (所有数据类型)
AssertionError断言语句失败
AttributeError对象没有这个属性
EOFError没有内建输入,到达EOF 标记
EnvironmentError操作系统错误的基类
IOError输入/输出操作失败
OSError操作系统错误
WindowsError系统调用失败
ImportError导入模块/对象失败
KeyboardInterrupt用户中断执行(通常是输入^C)
LookupError无效数据查询的基类
IndexError序列中没有没有此索引(index)
KeyError映射中没有这个键
MemoryError内存溢出错误(对于Python 解释器不是致命的)
NameError未声明/初始化对象 (没有属性)
UnboundLocalError访问未初始化的本地变量
ReferenceError弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError一般的运行时错误
NotImplementedError尚未实现的方法
SyntaxError Python语法错误
IndentationError缩进错误
TabErrorTab 和空格混用
SystemError一般的解释器系统错误
TypeError对类型无效的操作
ValueError传入无效的参数
UnicodeErrorUnicode 相关的错误
UnicodeDecodeErrorUnicode 解码时的错误
UnicodeEncodeErrorUnicode 编码时错误
UnicodeTranslateErrorUnicode 转换时错误
Warning警告的基类
DeprecationWarning关于被弃用的特征的警告
FutureWarning关于构造将来语义会有改变的警告
OverflowWarning旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning关于特性将会被废弃的警告
RuntimeWarning可疑的运行时行为(runtime behavior)的警告
SyntaxWarning可疑的语法的警告
UserWarning用户代码生成的警告

什么是异常?

异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。

异常处理

捕捉异常可以使用try/except语句。
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
如果你不想在异常发生时结束你的程序,只需在try里捕获它。
语法:
以下为简单的try…except…else的语法:

try:
<语句>        #运行别的代码
except <名字><语句>        #如果在try部份引发了'name'异常
except <名字><数据>:
<语句>        #如果引发了'name'异常,获得附加的数据
else:
<语句>        #如果没有异常发生

try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。

如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
实例
下面是简单的例子,它打开一个文件,在该文件中的内容写入内容,且并未发生异常:

#!/usr/bin/python

try:
   fh = open("testfile", "w")
   fh.write("This is my test file for exception handling!!")
except IOError:
   print "Error: can\'t find file or read data"
else:
   print "Written content in the file successfully"
   fh.close()

以上程序输出结果:

 Written content in the file successfully

实例
下面是简单的例子,它打开一个文件,在该文件中的内容写入内容,但文件没有写入权限,发生了异常:

#!/usr/bin/python

try:
   fh = open("testfile", "w")
   fh.write("This is my test file for exception handling!!")
except IOError:
   print "Error: can\'t find file or read data"
else:
   print "Written content in the file successfully"

以上程序输出结果:

Error: can't find file or read data

使用except而不带任何异常类型

你可以不带任何异常类型使用except,如下实例:

try:
   You do your operations here;
   ......................
except:
   If there is any exception, then execute this block.
   ......................
else:
   If there is no exception then execute this block. 

以上方式try-except语句捕获所有发生的异常。但这不是一个很好的方式,我们不能通过该程序识别出具体的异常信息。因为它捕获所有的异常。

使用except而带多种异常类型

你也可以使用相同的except语句来处理多个异常信息,如下所示:

try:
   You do your operations here;
   ......................
except(Exception1[, Exception2[,...ExceptionN]]]):
   If there is any exception from the given exception list, 
   then execute this block.
   ......................
else:
   If there is no exception then execute this block.  

try-finally 语句

try-finally 语句无论是否发生异常都将执行最后的代码。

try:
<语句>
finally:
<语句>    #退出try时总会执行
raise

注意:你可以使用except语句或者finally语句,但是两者不能同时使用。else语句也不能与finally语句同时使用
实例

#!/usr/bin/python

try:
   fh = open("testfile", "w")
   fh.write("This is my test file for exception handling!!")
finally:
   print "Error: can\'t find file or read data"

如果打开的文件没有可写权限,输出如下所示:

Error: can't find file or read data

同样的例子也可以写成如下方式:

#!/usr/bin/python

try:
   fh = open("testfile", "w")
   try:
      fh.write("This is my test file for exception handling!!")
   finally:
      print "Going to close the file"
      fh.close()
except IOError:
   print "Error: can\'t find file or read data"

当在try块中抛出一个异常,立即执行finally块代码。
finally块中的所有语句执行后,异常被再次提出,并执行except块代码。
参数的内容不同于异常。

异常的参数

一个异常可以带上参数,可作为输出的异常信息参数。
你可以通过except语句来捕获异常的参数,如下所示:

try:
   You do your operations here;
   ......................
except ExceptionType, Argument:
   You can print value of Argument here...

变量接收的异常值通常包含在异常的语句中。在元组的表单中变量可以接收一个或者多个值。

元组通常包含错误字符串,错误数字,错误位置。

实例
以下为单个异常的实例:

#!/usr/bin/python

# Define a function here.
def temp_convert(var):
   try:
      return int(var)
   except ValueError, Argument:
      print "The argument does not contain numbers\n", Argument

# Call above function here.
temp_convert("xyz");

以上程序执行结果如下:

The argument does not contain numbers
invalid literal for int() with base 10: 'xyz'

触发异常
我们可以使用raise语句自己触发异常

raise语法格式如下:

raise [Exception [, args [, traceback]]]

语句中Exception是异常的类型(例如,NameError)参数是一个异常参数值。该参数是可选的,如果不提供,异常的参数是"None"。

最后一个参数是可选的(在实践中很少使用),如果存在,是跟踪异常对象。

实例
一个异常可以是一个字符串,类或对象。 Python的内核提供的异常,大多数都是实例化的类,这是一个类的实例的参数。

定义一个异常非常简单,如下所示:

def functionName( level ):
   if level < 1:
      raise "Invalid level!", level
      # The code below to this would not be executed
      # if we raise the exception

注意:为了能够捕获异常,"except"语句必须有用相同的异常来抛出类对象或者字符串。

例如我们捕获以上异常,"except"语句如下所示:

try:
   Business Logic here...
except "Invalid level!":
   Exception handling here...
else:
   Rest of the code here...

用户自定义异常

通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自Exception类,通过直接或间接的方式。

以下为与RuntimeError相关的实例,实例中创建了一个类,基类为RuntimeError,用于在异常触发时输出更多的信息。

在try语句块中,用户自定义的异常后执行except块语句,变量 e 是用于创建Networkerror类的实例。

class Networkerror(RuntimeError):
   def __init__(self, arg):
      self.args = arg

在你定义以上类后,你可以触发该异常,如下所示:

try:
   raise Networkerror("Bad hostname")
except Networkerror,e:
   print e.args

二、测试

1.测试分类及单元测试

在编写完某程序时,为了测试功能的预期结果和我们想实现的结果是否一致,可以使用测试单元unittest。
在这里插入图片描述

2.unittest模块

语法:
import unittest测试用例
定义一个继承自unittest.TestCase(测试名称函数)的子类

在其中定义以test_开头的方法
使用断言语句,如self.assertEqual(运行结果,‘预期的结果’) 判断结果与预期结果是否一致
实例:
在这里插入图片描述
创建一个测试用例文件test_name_function.py
调用 unittest.main()
在这里插入图片描述
运行结果:OK,是对的

ok

将断言函数中的值故意写错
在这里插入图片描述
运行结果:
在这里插入图片描述

3.其他的断言函数

4.开发中标准的测试

创建一个test文件夹,将所有的测试代码都放入其中。
测试文件命名为待测文件名_test.py
导入unittest模块与待测试模块
创建类为 类名Test
方法名为 test_待测方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
运行结果
在这里插入图片描述
在这里插入图片描述

将函数定义初始化信息放入setUp()方法中,将测试执行完毕的清理工作放在tearDown()方法中
在这里插入图片描述

三、数值与日期

1.数值

格式化
’{}‘.format(a)或 f’{a}’ —— 打印a
‘{:f}’.foramat(a)或f’{a:f}’ —— 以浮点型打印a
‘{:+f}’.foramat(a)或f’{a:+f}’ —— 带加号的浮点型a
‘{:,f}’.foramat(a)或f’{a:,f}’ —— 千分位,间隔a
‘{:,.4f}’.foramat(a)或f’{a:,.4f}’ —— 以千分位间隔并保留小数点后四位(四舍五入)
‘{:.2%}’.foramat(a)或f’{a:.2%}’ —— 将a打印成带百分号并保留两位小数的形式

>>>a=520                         #整数int
>>>b=1234567890.123456           #浮点型float正数
>>>c=-123456.654321              #浮点型float负数
>>>type(a)                      #通过type检查类型
<class 'int'>
>>>type(b)                      #通过type检查类型
<class 'float'>
>>>type(c)                      #通过type检查类型
<class 'float'>
>>>'数值:{}'.format(a)            #{}占位符format,可以省去后面的函数调用
'数值:520'
>>>'数值:{}'.format(b)            #{}占位符format,可以省去后面的函数调用
'数值:1234567890.123456'
>>>f'数值:{a}'
'数值:520'
>>>f'数值:{b}'
'数值:1234567890.123456'
>>>'数值:{}',format(a)
'数值:520'
>>>'数值:{:f}',format(a)          #以浮点型打印看起来更精确
'数值:520.000000'
>>>f'数值:{a:f}'
'数值:520.000000'
>>>f'数值:{b:f}'
'数值:1234567890.123456 '
>>>f'数值:{c:f}'
'数值:-123456.654321'
>>>f'数值:{b:,f}'
'数值:1,234,567,890.123456'
>>>f'数值:{b:,2f}'
'数值:1,234,567,890.12'
>>>f'数值:{b:,4f}'
'数值:1,234,567,890.1235'

2.取整

math.trunc(数值) —— 截断
math.floor(数值) —— 向下取整
math.ceil(数值) —— 向上取整
四舍五入
round(数值 ,小数位数默认=0 ) —— 四舍五入

>>>a=520                         
>>>b=1234567890.123456           
>>>c=-123456.654321
>>>import math
>>>math.trunc(b)
1234567890 
>>>math.trunc(123.98)
123
>>>math.floor(b)
123 
>>>math.floor(123.98)
123    
>>>math.ceil(b)
124
>>>math.ceil(123.98)
124 
>>>math.ceil(123.123)
124

>>> round(b,2)              #round全局函数,四舍五入,后面数字代表保留几个小数后几位数
1234567890.12   
>>> round(b,3) 
1234567890.123           

3.随机数

random.choice(l) 序列中随机选择一个值
random.sample(l,3) 随机获取指定数目的序列
random.shuffle(l) 打乱顺序
random,randint(1,10) 生范围内的随机整数
random.random() 生成0-1的随机浮点数
random.getrandbits() 生成指定bit位数的随机数

lst = list(range(1,11))   #1到10列表
>>>import random
>>>random.choice(1st)     #随机获取列表的任意一个数
6
>>>random.choice(1st)     #随机获取列表的任意一个数
8
>>>random.sample(1st,3)   #随机获取列表的任意3个数
[3,6,9]
>>>lst
[1,2,3,4,5,6,7,8,9,10]
>>>random.shuffle(1st)    #随机打乱顺序
[10,8,3,4,5,6,7,2,9,1]
>>>random.randint(1st)    #随机在范围内生一个整数
9
>>>random.random()        #随机在范围内生一个整数
0.254643413131

四、日期与时间

import datetime

  • datetime.date
  • datetime.time
  • datetime.datetime
  • 字符串与日期的格式转换 —— datetime.datetime.strptime()
    -字符串到日期时间 datetime.datetime.strptime(str,‘格式’)
    -日期时间到字符串 datetime.datetime.strptime(‘格式’)
    -占位符:%Y 四位年份;%y 二位年份;%m 二位月份;%d 二位日期; %H 二位小时;%M 分钟;%S 二位秒数;%f 微秒 ;%W 星期数
>>>import datetime                    #获取时间
>>>datetime.MAXYEAR                   #最大年
9999
>>>datetime.MINYEAR                   #最小年
1
>>>today = datetime.date.today()      #获取今天的日期
>>>today                              #获取今天的日期 三个参数分别对应年月日
datetime.date(2020,2,19)
>>>today.year
2020
>>>today.month
2
>>>today.day
19
>>>today.weekday()                     #获取今天的周几,注意要加括号
2
>>>today.isoweekday()                  #获取国际今天的周几,注意要加括号
3
>>>birthdate = datetime.date(2018,3,12)  #生日日期,程序里日期间隔也是逗号,
>>>birthdate.year
2018
>>>birthdate.month
3
>>>birthdate.day
12
>>>t = datetime.time(15,46,32)           #时间,程序里时间间隔也是逗号,依依对应时分秒
>>>t.hour
15
>>>t.minute                      
46
>>>t.second
32
>>>now = datetime.datetime.now()           #获取当前时间和日期
>>>now
datetime.datetime(2020, 2, 19, 2, 15, 31, 563674)
>>>now.year
2020
>>>now.month
2
>>>now.second                             #获取当前秒(此处不是seconds,没有负数)
31
>>>now.microsecond                       #获取当前毫微秒
563674
>>>t = datetime.datetime(1990,3,30,20,20,44)    #自己构造时间
>>>t.month
3
>>>import datetime 
>>>s = '2018-3-15'
>>>type(s)
<class 'str'>             #字符串
>>>t = datetime.datetime.strptime(s,'%Y-%m-%d')      #转化能计算的格式日期
>>>t
datetime.datetime(2018, 3, 15, 0, 0)
>>>now = datetime.datetime.now()
>>>now
datetime.datetime(2020, 2, 19, 2, 33, 37, 216770)

>>>txt = now.strftime('%Y/%m/%d')             #转化日期格式
>>>txt
'2020/02/19'

时间差的处理

datetime.timedelta()
days = 100 —— 加100天
hours = -100 —— 减100小时
seconds = 100 —— 加100秒

>>>import datetime
>>>d = datetime.datetime(2018,2,3,22,25)
>>>birthdate = datetime.datetime(2016,5,2,19,38,50)  #数字不能超出实际范围,例如秒要小于60
>>> d - birthdate                                    
datetime.timedelta(days=642, seconds=9970)  #642,9970,是datetime.timedelta的属性
>>>diff = d-birthdate                       #把刚刚d-birthdate赋予一个变量diff              #
>>>diff.days
642
>>>diff.seconds
9970
>>>diff.total_seconds()
55478770.0
>>>o=datetime.datetime(2008,8,8,20,8)    #奥运会时间往后退100天
>>>o + datetime.timedelta(days=100)      #
datetime.datetime(2008, 11, 16, 20, 8)   #加上100天变成11月
>>>d
datetime.datetime(2018, 2, 3, 22, 25)   #刚才时间
>>>result = d + datetime.timedelta(days=-100)    #刚才时间往前推100天
>>>result
datetime.datetime(2017, 10, 26, 22, 25)
>>>d + datetime.timedelta(seconds=3000)         #刚才时间往前推3000秒天
datetime.datetime(2018, 2, 3, 23, 15)
>>>result.hour
22                                 #时间差22小时

五、总结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值