PYTHON基础知识学习笔记(八)

错误异常处理

在编写代码的过程中,难以避免的出现错误和异常,处理Python的错误或异常是构建稳定程序的重要组成部分。

错误类型

1、语法错误:输入代码时出现错误,如字母错误,标点符号错误,导致语法不正确,比较容易排除。
2、语义错误:语法没问题,但表达的内容不正确,如5/0。这种错误比语法错误处理起来稍加麻烦。
3、逻辑错误:与代码无关,整体程序设计有问题,这种错误最难改正。

当出现语法错误时,运行后会提示:SyntaxError

print('python)       #少输入一个’

#运行结果
File "E:/software/pycharm/project/main.py", line 1
    print('python)
                 ^
SyntaxError: EOL while scanning string literal

当出现操作异常时,运行后会提示:ZeroDivisionError

a = 5 / 0       #0不能作除数
print(a)

#运行结果
File "E:/software/pycharm/project/main.py", line 1, in <module>
    a = 5 / 0
ZeroDivisionError: division by zero

当出现属性异常时,运行后会提示:AttributeError

class Person:
    def __init__(self,name):
        self.name = name

p = Person('Peter')
print(p.age)                   #未定义该属性

#运行结果
File "E:/software/pycharm/project/main.py", line 6, in <module>
    print(p.age)
AttributeError: 'Person' object has no attribute 'age'

异常处理

异常处理主要针对代码层面的问题,因此主要处理语法错误及语义错误。
使用如下语句处理对应的代码:
1、try:有可能出现的代码。
2、except 异常 as 实例:捕获特定异常。
3、else:未遇异常时执行。
4、finally:不论是否遇到异常均会执行。
5、raise:手动抛出异常。

使用try及except语句可以捕获异常,自定义输出提示。

#正常运行
try:
    a = 5 / 2
    print(a)
except ZeroDivisionError:
    print('不能除零')
else:
    print('没有错误')
#运行结果
2.5
没有错误  


#除以0
try:
    a = 5 / 0
    print(a)
except ZeroDivisionError:
    print('不能除零')
else:
    print('没有错误')
#运行结果
不能除零
class Person:
    def __init__(self,name):
        self.name = name

p = Person('Peter')

try:
    print(p.age)          #未定义该属性
except AttributeError as a:
    print('遇到属性异常',a)

#运行结果
遇到属性异常 'Person' object has no attribute 'age'

如果在操作文件时遇到异常,需要通过添加finally语句将文件关闭,否则文件将一直处于打开状态。

f = open('data.txt')
try:
    f.read()
except:
    print('文件操作遇到错误!')    
finally:
    f.close()

当打算定义一个函数但还没有设计完成时,可以在函数下设置raise语句,提示代码还未完成。

def method():
    raise NotImplementedError('该代码还未实现')

method()

#运行结果
Traceback (most recent call last):
  File "E:/software/pycharm/project/main.py", line 4, in <module>
    method()
  File "E:/software/pycharm/project/main.py", line 2, in method
    raise NotImplementedError('该代码还未实现')
NotImplementedError: 该代码还未实现

unittest单元测试

unittest单元测试是对代码最基本单元(函数、方法)的测试,给予特定条件判断结果是否符合预期。相对整个程序的测试,单元测试简化了测试任务。

测试代码组织

代码结果正确时:

import unittest     #导入unittest模块

def add(a,b):       #定义待测试函数
    return a + b

class MyTest(unittest.TestCase):      #基于unittest.TestCase定义一个测试类
    def test_add(self):
        self.assertEqual(8,add(5,3))  #利用断言语句判断

if __name__ == '__main__':
    unittest.main()

运行结果
在这里插入图片描述
代码结果错误时:

import unittest     #导入unittest模块

def add(a,b):       #定义待测试函数
    return a + b

class MyTest(unittest.TestCase):      #基于unittest.TestCase定义一个测试类
    def test_add(self):
        self.assertEqual(8,add(5,4))  #利用断言语句判断

if __name__ == '__main__':
    unittest.main()

运行结果
在这里插入图片描述

常用断言

1、assertEqual():是否相等。
2、assertTure():是否为真。
3、assertIn():是否包含。
4、assertAlmostEqual():是否约等于。
5、assertIs():是否为同引用。
6、assertIsNone():是否为空。
7、assertIsInstance():是否为某类型实例。
8、assertGreater():是否大于。
······

类与测试装置

我们可以在主程序中定义自己的类与方法,再创建一个测试文件用于测试刚才自己定义的方法,将指定模块导入到测试文件中进行测试。
例,在主程序main.py中定义一个名为Calculator的类,其中包含两个类方法add、subtract。

#main.py
class Calculator:
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def add(self):
        return self.x + self.y
    def subtract(self):
        return self.x - self.y

if __name__ == '__main__':
    c = Calculator(5,3)

在另一个测试文件test.py中对该类的方法进行测试。

import unittest               #导入unittest模块
from main import Calculator   #导入主程序中定义的类

class CalculatorTest(unittest.TestCase): #基于unittest.TestCase定义一个测试类
    def setUp(self):                #将测试中的准备工作放入该方法,如类实例化
        self.c = Calculator(5,3)
    def test_add(self):
        self.assertEqual(8,self.c.add())        #利用断言语句判断方法add
    def test_subtract(self):
        self.assertEqual(2,self.c.subtract())   #利用断言语句判断方法subtract
    def tearDown(self):              #测试完成后将数据或链接清除
        del self.c

if __name__ == '__main__':
    unittest.main()

全部正确时,运行结果如下:
在这里插入图片描述
程序错误时
在这里插入图片描述
运行结果如下:
在这里插入图片描述
在这里插入图片描述

数值与日期

数值

格式化

首先定义三个数值

>>> a = 520
>>> b = 1234567890.123456
>>> c = -123456.654321
>>> type(a)
int
>>> type(b)
float
>>> type(c)
float

将数值原样显示出来

>>> '数值:{}'.format(a)
'数值:520'
>>> '数值:{}'.format(b)
'数值:1234567890.123456'
>>> f'数值:{a}'
'数值:520'
>>> f'数值:{b}'
'数值:1234567890.123456'

将整形数值以浮点型显示

>>> '数值:{:f}'.format(a)
'数值:520.000000'
>>> f'数值:{a:f}'
'数值:520.000000'

将位数多的数值以千分位显示

>>> f'数值:{b:f}'
'数值:1234567890.123456'
>>> f'数值:{b:,f}'
'数值:1,234,567,890.123456'

以百分比格式显示

>>> x = 18
>>> y = 23
>>> '{:.2%}'.format(x / y)
'78.26%'

小数位处理

保留指定的小数位(四舍五入)

>>> f'数值:{b:.2f}'
'数值:1234567890.12'
>>> f'数值:{b:.4f}'
'数值:1234567890.1235'
>>> x = 18
>>> y = 23
>>> '{:.2f}'.format(x / y)
'0.78'

截断小数点后的内容(直接截断,未四舍五入)

>>> import math
>>> math.trunc(123.987)
123

向下取整

>>> math.floor(3.6)
3
>>> math.floor(-2.3)
-3

向上取整

>>> math.ceil(3.6)
4
>>> math.ceil(-2.3)
-2

四舍五入

>>> round(123456.123456,3)
123456.123
>>> round(123456.123456,4)
123456.1235

随机数

生成随机数使用random模块。
随机从一个序列中得到一个值

>>> lst = list(range(1,11))
>>> lst
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> import random
>>> random.choice(lst)
9
>>> random.choice(lst)
2

随机从一个序列中得到指定数量的值

>>> random.sample(lst,3)
[8, 2, 6]
>>> random.sample(lst,4)
[9, 5, 4, 6]

将指定序列打乱

>>> lst
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> random.shuffle(lst)
>>> lst
[9, 3, 8, 7, 2, 4, 10, 6, 5, 1]

在某一范围内随机取一个整数

>>> random.randint(1,10)
3
>>> random.randint(1,10)
1

随机取一个大于0小于1的浮点型数值

>>> random.random()
0.7278014028468106
>>> random.random()
0.4930686142921825

随机生成一个指定比特位数的数值

>>> random.getrandbits(5)
28

日趋时间

使用日期与时间需导入datetime模块。

获取日期时间

datetime模块可显示的最大年份与最小年份

>>> import datetime
>>> datetime.MAXYEAR
9999
>>> datetime.MINYEAR
1

获取今天的日期及具体信息

>>> today = datetime.date.today()
>>> today
datetime.date(2020, 2, 15)
>>> today.year
2020
>>> today.month
2
>>> today.day
15
>>> today.weekday()       #从0开始计数,今天是周六
5
>>> today.isoweekday()    #从1开始计数,按照国际惯例
6

也可以构造一个日期,使用方法和上文的today一样

>>> birthday = datetime.date(2010,2,12)
>>> birthday
datetime.date(2010, 2, 12)
>>> birthday.year
2010

只构造一个时间,不需要日期

>>> t = datetime.time(15,46,32)
>>> t
datetime.time(15, 46, 32)
>>> t.hour
15
>>> t.minute
46
>>> t.second
32

获取当前的日期及时间

>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2020, 2, 15, 18, 28, 57, 805300)
>>> now.year
2020
>>> now.hour
18

自己构造一个日期及时间

>>> t = datetime.datetime(1990,3,3,20,33,44)
>>> t
datetime.datetime(1990, 3, 3, 20, 33, 44)
>>> t.month
3
>>> t.minute
33

日期时间与字符串间的转换

字符串转换为时间

>>> s = '2018-3-15'
>>> type(s)
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, 15, 18, 38, 38, 699776)
>>> txt = now.strftime('%Y/%m/%d')
>>> txt
'2020/02/15'

日期时间与字符串转换中常用的占位符
1、%Y:四位年份
2、%y:二位年份
3、%m:二位月份
4、%d:二位日期
5、%H:二位小时
6、%M:二位分钟
7、%S:二位秒数
8、%f:微秒
9、%w:星期数 0,1,···,6
······

时间差

两个时间点相减可得时间差

>>> d = datetime.datetime(2018,3,5,22,44)
>>> brithdate = datetime.datetime(2016,5,2,19,33,44)
>>> diff = d - brithdate
>>> diff
datetime.timedelta(days=672, seconds=11416)    #672天零11416秒
>>> diff.days           #天数
672
>>> diff.seconds        #余下的秒数
11416
>>> diff.total_seconds()  #总共包含的秒数
58072216.0

以某一时间点向后或向前推一段时间

>>> o = datetime.datetime(2008,8,8,20,8)
>>> result1 = o + datetime.timedelta(days = 100,seconds = 3000)
>>> result1
Out[99]: datetime.datetime(2008, 11, 16, 20, 58)
>>> result2 = o + datetime.timedelta(days = -100)
>>> result2
datetime.datetime(2008, 4, 30, 20, 8)

未完待续!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值