错误和异常 一个单例实现

单例类

用装饰器实现单例类

1、引用

def singleton(cls):
   instance = None
   def gey_instance(*args, **kwargs):
       nonlocal instance
       if not instance:
           instance = cls(*args, **kwargs)
       return instance
   return gey_instance()

@singleton    # cls = Text   Text----->gey_instance
class Text(object):
   def __init__(self,name,age):
   pass

t1 = Text("aaa",23)    # instance
t2 = Text("bbb",24)    # instance


def singleton(cls):
   instancedict = {}
   def gey_instance(*args, **kwargs):
       if not instancedict:
           instancedict[cls] = cls(*args, **kwargs)
       return instancedict[cls]
   return gey_instance()

@singleton    # cls = Text   Text----->gey_instance
class Text(object):
   def __init__(self,name,age):
   pass

t1 = Text("aaa",23)    # instancedict[cls]
t2 = Text("bbb",24)    # instance[cls]

错误和异常

概念

python中有两种错误比较容易辨认:语法错误【直接报错】和异常【代码正常,运行错误】
有些异常时输入造成的,有些异常时代码执行过程成中的突发状况,比如:写入文件,磁盘满了,或者从网络上抓取数据,但是网络突然断掉等

异常的特点:在代码执行的过程中遇到了异常,而且未被处理,则代码会终止向下执行,整个程序结束。

处理异常的方式:想办法将可能出现异常的代码检测起来,当异常出现的时候,将出现异常的代码“屏蔽起来”,为了让后面的代码继续执行

常见的异常:

# NameError:当一个变量或者函数违背定义就是用
# print(num)   # NameError: name 'num' is not defined


# 2、KeyError: 访问字典不粗不在的key
# dict1 = {"a": 1}
# print(dict1["b"])   # KeyError: 'b'

# ValueError:当类型转换的时候【int,float】
# s = int("faf")   # ValueError: invalid literal for int() with base 10: 'faf'


# 4、TypeError:当类型不匹配的时候
# print("a" + 18)  # TypeError: must be str, not int


# 5、AttributeError:当试图访问一个对象不存在的属性或者函数
# print("faf".resverse())  # AttributeError: 'str' object has no attribute 'reverse'


# 6、UnboundLocalError:变量的作用域不明确的时候
# num = 10
# def test():
#     num +=1
# test()    # UnboundLocalError: local variable 'num' referenced before assignment

# 7、IndexError   下标异常错误
# 8、ImportError   导入模块错误
# 9、SyntaxError    语法错误

处理异常

try-except-else/finally 捕获

try:
 语句1
except 错误标识码1 as 变量:
 语句2
else/finally:
  语句n

说明:
a、try语句被称为检测区
b、except表示try中的语句出现异常,需要处理的语句,可以省略,可以写一个或者多个
c、else可以省略,组合语句【try-except-else】,或者【try-else】
d、finally也可以省略,组合语句【try-except-finally】或者【try-finally】
e、如果try中的代码存在异常,则执行顺序try-except----》finally
f、如果try中代码不存在异常,则执行try-finally

# 1、只是用一个except
try:
    list1 = [23, 54, 54, 5, 6]
    print(list1[1])
    # 注意:在Python中,异常也被面向对象化了,出现的具体的异常就是一个对象,对象的类型在出现异常的时候已经被确定
    print(list1[10])

    print("hello")
# IndexError是一个错误标识码,实际上时一个系统类
# e只是一个变量名,指向当前出现的异常的对象,e = IndexError()
except IndexError as e:
    # 默认直接打印对象,结果为该对象在内存中的地址,但是,直接打印e结果为一个信息描述,
    # 原因:在异常类中,已经被改写了
    print(e)

print("over")

# 注意:如果try中的代码出现异常,如果要处理异常,则必须尊在一个匹配的except语句,否则原本的异常仍然未被处理

# 2、使用多个except
try:
    num = int(input("请输入数字"))
    list1 = [23, 54, 54, 5, 6]
    print(list1[num])
    print("hello")
except IndexError as e:
    print(e)
    
except ValueError as e:
    print(e)
print("over")

# 注意;当try的异常肯恩给存在多个,则需要打印except语句匹配,不管出现多少个except,都只会匹配其中一个
#      不管try中出现多少个异常,不管书写了多少个except,都只会处理器中一个异常【像极了if多分支】
# 原理:根据据try中出现的异常类型进行匹配执行的except,从上至下,匹配类型,否则指定的一场仍然存在

# 3、错误的标识码为父类
# 系统的异常都是类,他们共同的父类为BaseExcept-----》Except----》object
try:
    num = int(input("请输入数字"))
    list1 = [23, 54, 54, 5, 6]
    print(list1[num])
    print("hello")
except BaseException as e:
    print(e)
    print('BaseException')
except ValueError as e:
    print(e)
print("over")

# 注意:当父类出现在except的第一条时,会包揽多有的异类,使用了多态【e可以有两种数据类型,一种是BaseException,另一种是写的】
     
# 4、
try:
    num = int(input("请输入数字"))
    list1 = [23, 54, 54, 5, 6]
    print(list1[num])
    print("hello")
# 可以匹配所有异常,但是缺点:不能确定是那种异常
except :
    print("出现了异常")
print("over")

# 5、
try:
    num = int(input("请输入数字"))
    list1 = [23, 54, 54, 5, 6]
    print(list1[num])
    print("hello")
# 可以匹配元组中指定的异常,相比较4,仅仅是缩小了范围
except (TypeError, IndexError, ValueError, NameError):
    print("出现了异常")
print("over")

# 6.else语句:只有当try中的语句没有任何异常的时候,才会被执行
try:
    num = int(input("请输入数字"))
    list1 = [23, 54, 54, 5, 6]
    print(list1[num])
    print("hello")
except BaseException as e:
    print(e)
    print('BaseException')
except ValueError as e:
    print(e)
else:
    print("..........")

# 7.finally语句:不管try中的语句是否存在异常,都会被执行
# try:
#     num = int(input("请输入数字"))
#     list1 = [23, 54, 54, 5, 6]
#     print(list1[num])
#     print("hello")
# except BaseException as e:
#     print(e)
#     print('BaseException')
# except ValueError as e:
#     print(e)
# finally:
#     print("..........")

# 特殊情况
def show():
    try:
        num = int(input("请输入数字"))
        list1 = [23, 54, 54, 5, 6]

        return

        print(list1[num])
        print("hello")
    except BaseException as e:
        print(e)
        print('BaseException')
    except ValueError as e:
        print(e)
    finally:
        print("..........")
    print("over")

show()

# 8、省略掉Except语句,如果try中没有异常,则执行finally,如果有异常,则直接报出异常
try:
    num = int(input("输入:"))
    print(10/num)
finally:
    print('finally')

raise 抛出

在异常中,异常对象的出现有两种方式;1、根据具体的问题体现 2、通过系统的异常类创建对象
语法:raise 异常对象

# raise关键字的作用:代码中没有异常,通过具体的需求在程序中的某个地方出现一个异常
# 则需要抛出一个具体的异常的对象,最终还是需要通过try-except捕获

# a、具体的代码
# print(10/0)
# try:
#     print(10/0)
# except ZeroDivisionError as e:
#     print(e)
try:
    raise ZeroDivisionError("除数不能为0")
except ZeroDivisionError as e:
    print(e)
    
# raise:raise关键字一般结合自定义异常的使用,系统的异常一般都是具体的问题体现的

assert 断言

def divide(num1,num2):
    # 在可能存在异常的代码添加一个断言【预测】,如果预测成功,则后面的代码不执行,报出一个AssertError
    assert num2 != 0, "~~~~除数不能为0~~~~"

    return num1/num2


print(divide(19, 0))

print():辅助调试
assert:替代print,在可能存在问题的代码处设置一个断言,如果断言成功,则代码正常执行,如果断言失败,则会报出AssertError

4、自定义异常

自定义异常的原理:需要继承自系统的异常类,为了保持系统的异常机制

# 1、定义类,继承自系统的异常类【继承自BaseException或者Exception】

class MyException(BaseException):
    # 2、书写构造函数,调用父类的构造函数
    # message用来记录异常的描述信息,为一个字符串
    def __init__(self,message):

        # 3、调用父类的构造函数
        super(MyException,self).__init__()

        self.message = message

    # 4、重写str函数,当打印异常的对象时候,得到的结果为异常的信息
    def __str__(self):
        return str(self.message)

    # 5、定义普通的成员函数,当一场出现的时候,需要解决异常
    @staticmethod
    def handle():
        print("处理了异常")


try:
    raise MyException("出现了异常")
except MyException as e:
    print(e)
    MyException.handle()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值