# 什么时异常?
    在程序运行过程中影响程序正常运行的内容,


# 为什么需要异常处理?
    可以让你的程序更加健壮, 可以清晰的快速修复异常。



常见的异常


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).d = dict(a=1, b=2)
d
{'a': 1, 'b': 2}
d['c']
KeyError: 'c'
异常处理的语句
"""
try......except... else......finally......


"""
# 普通的异常处理:
# 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))
# finally:
#     # 无论是否出现异常, 肯定会执行一次,
#     print("处理结束")


import  time
try:
    # 如果你觉得代码可能出现问题, 那么放在try语句中, 只执行一次;
    print('hello')
    with open('/etc/aa') as f:
        print(f.read()[:5])

    print("文件读取结束")
    li = [1, 2, 3, 4]   # try语句中一旦出现问题, 后面的语句(try里面的)不执行
    print(li[5])
    print(s)
    print("hello")
except (NameError, IndexError) as e:   # 对于异常进行一个重命名;记录了异常的详细信息;
    # 可能执行一次, 也可能不执行;
    # print("名称错误")
    with open("except.log", 'a+') as f:
        f.write(time.ctime() + ' ' + str(e) + '\n')
finally:
    # 无论是否出现异常, 肯定会执行一次,
    print("处理结束")
官方范例

# 1).
# class B(Exception):
#     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")



# 2.
import sys
# /etc/passwd /etc/group
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()
抛出异常
# try....except...finally  ===== 捕获异常
# raise ======   抛出异常
class AgeError(Exception):
    pass

if age < 0 or age > 120:
    raise  AgeError
else:
    print(age)
调试断点之assert
"""
Assert statements are a convenient way to insert debugging assertions into a program:
assert语句是一种插入调试断点程序的一种便捷的方式。

assert语句的使用格式
        assert expression

这个语句是等价于下面的个句式:

        if __debug__:
            if not expression: raise AssertionError
"""


# age = int(input('Age:'))
# assert   0<age<120, "年龄不合法"


def is_huiwen_num(num):
    snum = str(num)
    return snum == snum[::-1]



def is_prime(num):  # 1 2
    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(1001) == True, 'Error'
    #     assert is_huiwen_num(101) == False, 'Error'
    # except AssertionError as e:
    #     print(e)
    # else:
    #     print("测试用例全部通过...")


    try:

        for num in [3,7,11,13]:
            assert is_prime(num) == True, ' %s Error' %(num)
        for num in [12,20,99999,132]:
            assert is_prime(num) == False, ' %s Error' %(num)

    except AssertionError as e:
        print(e)
    else:
        print("测试用例全部通过...")
"""
日志是用来记录程序在运行过程中发生的状况,在程序开发过程中添加日志模块能够帮助我们了解程序运行过程中发生了哪些事件,这些事件也有轻重之分。
根据事件的轻重可分为以下几个级别:

	DEBUG: 详细信息,通常仅在诊断问题时才受到关注。整数level=10
	INFO: 确认程序按预期工作。整数level=20
	WARNING:出现了异常,但是不影响正常工作.整数level=30
	ERROR:由于某些原因,程序 不能执行某些功能。整数level=40
	CRITICAL:严重的错误,导致程序不能运行。整数level=50

默认的级别是WARNING,也就意味着只有级别大于等于的才会被看到,跟踪日志的方式可以是写入到文件中,也可以直接输出到控制台。


"""
日志处理之logging
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("数据信息删除失败")