异常处理
异常:
在程序运行过程中影响程序正常运行的内容
常见的异常:
1) 名称错误
print(s)
NameError: name 's' is not defined
2) 索引错误
li = [1,2,3]
li[10]
IndexError: list index out of range
3) 除零错误
10/0
ZeroDivisionError: division by zero
4) key值错误
d = dict(a=1, b=2)
d['c']
KeyError: 'c'
5) 属性错误
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
def echo(self):
return self.name
def __str__(self):
return "Student(%s)" %(self.name)
s = Student('黎明', 30)
print(s.scores)
s.echo1()
AttributeError: 'Student' object has no attribute 'scores'
AttributeError: 'Student' object has no attribute 'echo1'
6) 文件找不到
with open('/tmp/aa') as f:
print(f.read()[:10])
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/aa'
异常结构
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
异常处理:
为什么需要异常处理?
因为异常处理可以让你的程序更加健壮, 可以清晰的快速修复异常。
语句: try…except… else…finally…
示例1:
import time
try:
# 如果你觉得代码可能出现问题, 那么放在try语句中, 只执行一次;
print(s)
print("hello")
except NameError as e: # 对于异常进行一个重命名;记录了异常的详细信息;
# 可能执行一次, 也可能不执行;
print("名称错误")
with open("except.log", 'w') as f:
f.write(time.ctime() + ' ')
f.write(str(e) + '\n')
finally:
# 无论是否出现异常, 肯定会执行一次,
print("处理结束")
运行结果:
生成的日志文件:
示例2:
import time
try:
# try语句只执行一次
print('hello')
with open('/etc/aa') as f:
print(f.read()[:5])
print("文件读取结束")
# try语句中一旦出现问题, 后面的语句(try里面的)不执行
li = [1, 2, 3, 4]
print(s)
print("hello")
except (NameError, IndexError, FileNotFoundError) as e:
with open("except.log", 'a+') as f:
f.write(time.ctime() + ' ' + str(e) + '\n')
finally:
# 无论是否出现异常, 肯定会执行一次,
print("处理结束")
运行结果:
生成的日志文件:
官方案例:
class A(Exception):
pass
class B(A):
pass
class C(B):
pass
class D(C):
pass
for cls in [B,C,D]:
try:
raise cls()
except D:
print('D')
except C:
print('C')
except B:
print('B')
import sys
# sys模块接收脚本传入的参数
for arg in sys.argv[1:]:
try:
f = open(arg,'r')
except OSError:
print('cannot open', arg)
else:
# 如果try语句中没有产生任何异常和错误, 才执行的语句;
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
sys模块
print(sys.argv)
返回的是一个列表, 第一个元素是脚本名称,后面一个元素是脚本后传入的参数
print(sys.argv[1:])
返回脚本传入的参数
抛出异常
try…except… else…finally… ==== 捕获异常
raise ==== 抛出异常
示例:
age = int(input("Age:"))
class AgeError(Exception):
pass
if age < 0 or age > 120:
raise AgeError
else:
print(age)
调试断点之assert
assert语句是一种插入调试断点程序的一种便捷的方式。
assert语句的使用格式:assert expression(表达式)
这个语句是等价于下面的这个句式:
if __debug__:
if not expression: raise AssertionError
示例:
def is_huiwen_num(num):
snum = str(num)
return snum == snum[::-1]
def is_prime(num):
assert num > 1
from math import sqrt
for i in range(2,int(sqrt(num) + 1)):
if num % i == 0:
return False
else:
return True
if __name__ == '__main__':
try:
assert is_huiwen_num(101) == True, 'Error'
assert is_huiwen_num(123) == False, 'Error'
except AssertionError as e:
print(e)
else:
print('测试用例全部通过...')
try:
for num in [3,7,11,13]:
assert is_prime(num) == True, 'Error'
for num in [12,20,99999,132]:
assert is_prime(num) == False, 'Error'
except AssertionError as e:
print(e)
else:
print('测试用例全部通过...')
日志处理之logging
日志是用来记录程序在运行过程中发生的状况,在程序开发过程中添加日志模块能够帮助我们了解程序运行过程中发生了哪些事件,这些事件也有轻重之分。
根据事件的轻重可分为以下几个级别:
DEBUG: 详细信息,通常仅在诊断问题时才受到关注。整数level=10
INFO: 确认程序按预期工作。整数level=20
WARNING:出现了异常,但是不影响正常工作.整数level=30
ERROR:由于某些原因,程序 不能执行某些功能。整数level=40
CRITICAL:严重的错误,导致程序不能运行。整数level=50
默认的级别是WARNING,也就意味着只有级别大于等于的才会被看到,跟踪日志的方式可以是写入到文件中,也可以直接输出到控制台。
示例:
import logging
# 配置日志的信息:
# 1). 日志级别: debug, info, warning, error, critical
# 2). level: 指日志级别为info及以上的日志信息会被记录到文件中;
# 3). format: 指定日志的格式, 可以去logging.Formatter查看参考信息
logging.basicConfig(filename='my.log', level=logging.WARN, format="%(asctime)s-%(filename)s-%(lineno)d- %(levelname)s: %(message)s ")
logging.debug("这是一个调试信息")
logging.error("数据库更新失败")
logging.critical("数据信息删除失败")
生成的日志文件: