单例类
用装饰器实现单例类
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()