异常以及异常处理

一、异常

程序执行过程中出现的非正常流程现象

二、异常处理的格式

1.异常处理格式一

"""
最简单语法格式1
try:
____可能引发异常现象的代码
except:
____出现异常现象的处理代码
"""

print("程序开始")
try:
    # i = 5
    print(i)  # 此时i没有定义
except:
    print("前面的代码有异常")
print("程序结束")

运行结果:
程序开始
前面的代码有异常
程序结束

 

# try下面的代码有部分异常
print
("程序开始了") try: # 这里的代码有可能引发异常 i = 5 print(i) # a = 10 print(a) except: print("24-27行代码之间出现了异常") print("程序结束了")

运行结果:
程序开始了
5
24-27行代码之间出现了异常
程序结束了


# 代码由上至下执行,打印”程序开始了“之后,开始进入try代码中,检查try下面的代码i= 5,并打印了5,再往下,a没有定义,到了”print(a)“,代码异常,就跳过进入了except中,打印了”
24-27行代码之间出现了异常

再往下打印了”程序结束了“

 

# try下面的代码中,中间部分的代码异常

print
("程序开始了") try: # 这里的代码有可能引发异常 i = 5 print(i) # a = 10 print(a) b = 6 print(6) except: print("24-27行代码之间出现了异常") print("程序结束了")


运行结果:

程序开始了
5
24-27行代码之间出现了异常
程序结束了


# 代码由上至下执行,打印”程序开始了“之后,开始进入try代码中,检查try下面的代码i= 5,并打印了5,再往下,a没有定义,到了”print(a)“,代码异常,就跳过进入了except中,打印了”
24-27行代码之间出现了异常

# print(a)下面的代码没有问题,所以但是程序并没有执行,当再try里面的代码中,当一遇到问题,在try中,代码就会终止执行,直接进入except中
总结:
python是解释性语言,代码执行至上而下
1.当没有遇到异常,就会执行try里面的代码
2.当遇到异常就会执行except中的代码
3.代码从上至下执行,try前面的代码没有问题,后面的代码有异常,它会执行完前面的代码,然后遇到异常后,转到except中执行
4.代码执行,当try上中下三行代码,上和下的代码没有问题,中间的代码有问题,那么执行完上面的代码后,就会转到except代码中

 

2. 异常处理格式2

"""
语法格式二
最简单语法格式1
try:
____可能引发异常现象的代码
except:
____出现异常现象的处理代码
finally:
____try代码快结束后运行的代码
"""
print("程序开始了")    # 成功执行

f = open("1.txt", "r", encoding="utf8")   # 这里启动的模式是r,需要关闭文件之后,在拿到文件句柄进行写操作
f.write("hello world!!!")  # 引发异常
f.close()   # 执行不到

print("程序结束了")   # 执行不到

# 当read模式成功执行后,因为后面的write方法与模式对应不上,报错导致后面的代码都无法执行了,进而引发这个文件的资源没有释放


运行结果:

FileNotFoundError: [Errno 2] No such file or directory: '1.txt'
程序开始

# 解决方式1:
print("程序开始了")    
try:
f = open("1.txt", "r", encoding="utf8")
f.write("hello world!!!") # 引发异常
f.close()
except:
f.close()
print("出现异常")
print("程序结束了")


运行结果:

程序开始了
出现异常
程序结束了





# 当出现了这种情况的时候
# 从代码上看try中的代码没有问题,但是没有关闭文件操作,这样文件的资源就有可能不会得到释放,但是又不会进入except,所以为了确保文件得到释放,还需要上一道保险

print("程序开始了")
try:
f = open("1.txt", "r", encoding="utf8")
f.read() # 引发异常

except:
f.close()
print("出现异常")
print("程序结束了")

运行结果:

程序开始了
程序结束了

 
print("程序开始了")
try:
f = open("1.txt", "r", encoding="utf8")
f.read()
# f.close()

except:
f.close()
print("出现异常")
time.sleep(30)
finally:
f.close()
print("已执行文件关闭")
print("程序结束了")

运行结果:

程序开始了
已执行文件关闭
程序结束了

# 不管try中的代码是不是有问题,except有没有执行,代码都会执行finally下面的代码

3.异常处理方式3

"""
语法格式三
最完整语法格式
try:(必选)
____可能引发异常现象的代码
except:(必选:二选一)
____出现异常现象的处理代码
else:(可选)
____未出现异常现象的处理代码
finally:(必选:二选一)
____try代码快结束后运行的代码
"""
print("程序开始")

try:
    i = 5
    print(i)
except:
    print("try中的代码有异常")
else:
    print("try中代码没有异常")
finally:
    print("比执行的代码")


print("程序结束")

 

三.捕获具体异常

"""
捕获具体异常
except 异常名:
"""
# i = 1/0
# print(i)

# ZeroDivisionError: division by zero

# 我们知道前面这几行代码是ZeroDivisionError异常


print("程序开始了")
try:
i = 1/0
print(i)
except NameError:
print("出现命名异常")
except ZeroDivisionError:
print("0不能作分母")
print("程序结束了")

运行结果:

程序开始了
0不能作分母
程序结束了

# 当遇到异常的时候,程序会走到相对应的异常类型里面

print("程序开始了")

try:
    # i = "hello world"
    print(a)
    print(a.index("a"))    # 这里的异常是value异常
except NameError:
    print("变量i没有被定义")
except ValueError:
    print("字符串中没有该字符,憨批")
except IndentationError:
    print("缩进错误")

print("程序结束了")


运行结果:
程序开始了
变量i没有被定义
程序结束了

在上面的异常,都是我们可以预知到的异常,还有一些我们无法预知的异常,如果程序检索不到下面的具体异常,依然会报错

print("程序开始了")

try:
    i = "hello world"
    print(i)
    print(i.index("a"))    # 这里的异常是value异常
except NameError:
    print("变量i没有被定义")
except IndentationError:
    print("缩进错误")

print("程序结束了")

运行结果:
程序开始了
hello world
Traceback (most recent call last):
  File "D:/zgzeng/pychon基础/异常处理/4-捕获异常.py", line 80, in <module>
    print(i.index("a"))    # 这里的异常是value异常
ValueError: substring not found

这样我们就需要用到一个大范围的异常来我们自己未知异常,防止报错

print("程序开始了")

try:
    a = "hello world"
    print(a)
    print(a.index("o"))    # 这里的异常是value异常
    j = 1/0
except NameError:
    print("变量i没有被定义")
except ValueError:
    print("字符串中没有该字符,憨批")
except IndentationError:
    print("缩进错误")
except Exception:   # 无差别捕获  未知的错误  放在最后面
    print("未知的错误")

print("程序结束了")


运行结果:
程序开始了
hello world
4
未知的错误
程序结束了

四、捕获异常具体信息

NameError:name 'a' is not defined

# NameError是异常类名
# name 'a' is not defined异常具体信息



"""
except 异常类名 as e:
"""
try:
# i = 5
print(i)
except NameError as e: # e只是一个变量名,我们可以设置为别的变量名,用来赋值给具体异常信息
print("具体的异常信息是:{}".format(e))

运行结果:
具体的异常信息是:name 'i' is not defined

# 这里将NameError的异常具体信息复制给了e

 

五、自定义异常

异常是一个类,Exception

为什么需要一个自定义异常,是因为我们有时候要写一个异常信息提示的时候,如果直接将原生的异常类写入,这样可能会影响这个类之后的使用,所以自定义一个异常,另外还有一些异常并不是原生异常类都能处理到,所以我们需要自定义异常

"""
自定义异常类
子类>>> 父类exception
定义类

"""

 

# 写一个程序,将下列不可以参军的人标记出来

info = {"小刚": 14} for name in info: if info[name] >= 18: print(f"{name}可以去当兵") else: print(f"{name}不能去当兵")

也可以用异常来标记

class AgeError(Exception):
pass


def check(info):
for s in info.keys():
global s1
s1 = s
if info[s] < 18:
raise AgeError("年龄不符合")
print(f"{s1}可以去当兵")

try:
check({"小平": 15})
except AgeError as e:
print(f"{s1}不能去当兵")



# raise AgeError("年龄不符合") raise声明这个异常,而括号里面的东西是异常具体信息

六.案例

"""
要求:
    用户名输入用户名,密码后对信息进行校验
    1.用户名长度再3-8个字符
    2.用户名中只能出现英文字母和数字
    3.密码长度必须是6位
    4.密码必须由纯数字组成

"""
# 1.通过用户输入去得到用户名和密码

usr_name = input("请输入您的用户名:")
usr_password = input("请输入您的密码:")

# 自定义异常,用来抛出,使得程序报错
class NameIsError(Exception):
    pass

class NameClassError(Exception):
    pass

class PasswordLengthIsError(Exception):
    pass

class PasswordIsError(Exception):
    pass



def check(name, pwd):
    """
    判断用户名和密码是否符合要求规范
    :param name: 用户名
    :param pwd: 密码
    :return: none
    """

    if len(name) not in range(3, 9):
        raise NameIsError("用户名的长度不在要求3-8个字符之间")

    if not name.isalnum():
        raise NameClassError("用户名中只能出现英文字母和数字")

    if not len(pwd) == 6:
        raise PasswordLengthIsError("密码的长度必须是6个字符")

    if not pwd.isnumeric():
        raise PasswordIsError("密码必须由纯数字组成")


try:
    check(usr_name, usr_password)
except NameIsError as e:
    print("用户名长度必须是3-8个字符之间")
except NameClassError as e:
    print("用户名由英文字母和数字组成")
except PasswordIsError as e:
    print("密码由纯数字组成")
except PasswordLengthIsError as e:
    print("密码由6个字符组成")

 

posted @ 2020-06-14 18:03  zgzeng  阅读(255)  评论(0编辑  收藏  举报