异常和设计模式都是Python中一些常见的知识点,设计模式包含对某类特定问题的解决方案,而异常则是Python中对于错误信息的处理方式。
目录
设计模式就是一种已经完善的解决方案,我们遇到类似的问题时,不需要我们自己动手再去重写解决方案,只需要调用已经完善的解决方案。这就属于一种设计模式。
单例设计模式就是指凡是用同一个特定的类名创建出来的对象都是引用同一块内存空间,这就表明我们创建的对象本质上都是同一个对象,这种设计模式就是单例设计模式。要想实现单例设计模式,我们首先要来看看一个对象是怎么具体创建的。当我们创建一个对象时,我们会调用类中创建对象的相关方法。其中创建一个对象主要需要两种方法:分配对象空间和初始化对象。我们不难看出,要是想实现单例设计模式,我们就需要首先对分配对象空间的方法进行改造。这个方法就是__new__方法。
这个方法在类中就是负责为新对象分配内存空间的,它是一个静态方法。而且它如果没有被重写的话是会被自动调用的。__new__方法是一个基类内部定义的方法,即object这个类里定义的方法,它虽然是静态变量,但是它也会需要接收一个参数,这个参数就是需要重写__new__方法的类的位置。调用它后它会返回一块新对象的内存地址。如果我们重写这个函数,想要完成单例设计模式,我们需要让这个方法返回同一个引用。
- class Info(object):
-
- instance = None
-
- def __new__(cls, *args, **kwargs):
-
- if cls.instance is None:
-
- cls.instance = super().__new__(cls)
- return cls.instance
-
- else:
-
- return cls.instance
上面我们用了一个判断分支结构,让除了第一次后的每一次都返回同一个内存地址,这样就能够实现单例设计模式了。
与前面的分配内存的方法相对应的是初始化的方法,如果我们要实现单例设计模式,我们设计的对象都是同样的引用,那么此时我们就应该设计初始化方法只调用一次。要想实现这个方法,我们需要做的事与前面的类似:
- class Info(object):
-
- instance = None
- flag = None
-
-
- def __init__(self):
-
- if Info.flag is None:
- print("初始化")
- Info.flag = 1
- else:
- return
异常就是指在程序运行过程中遇到错误后解释器停止程序并且将错误信息返回提示的过程。并不是说代码符合语法就会没有异常,如果用户操作有误也会带来异常。
因为在程序执行出现错误时,解释器会停止执行并且抛出异常,所有我们对应地也有一个捕获异常的操作。即当我们执行一些可能报错的程序时,我们可以在那个可能有问题的程序前加上try关键字,后加上except关键字,此时当try关键字里的程序出现问题时,程序不会终止执行,而会去执行except里面的代码,这样就不会造成程序终止。但是有时候我们程序抛出的错误可能有很多种,此时我们就需要根据捕获的错误信息来具体设置不同的解决方案。错误信息就是系统抛出的异常信息最后一行第一个词。
- try:
- a = int(input())
- 1/a
- except ValueError:
- print("类型错误")
- except ZeroDivisionError:
- print("0不能做分母")
但是有时候我们并不能够确保我们能够捕获到所有的错误信息,所以我们应该还设计一个接收未知的错误信息的方案来接收编译器抛出的其它的错误信息。这个方案就是一个额外的except分支,它的错误信息项需要写:Exception as 某个变量名(随便一个)然后这个变量就会接收这些未知的错误信息,要是我们想处理这些信息,还可以将其输出:
- try:
- a = int(input())
- 1/a
- except ValueError:
- print("类型错误")
- except ZeroDivisionError:
- print("0不能做分母")
- except Exception as error:
- print(error)
其实捕获异常的捕获结构完整来说还应该包括有else和finally两部分,其中else里面的语句表示只有在程序没有错误时才会执行,而finally结构里面的语句表示无论如何都会被执行。所以完整的捕获结构图如下:
说到异常就不得不提异常的传递性,异常的传递性指出现异常后到程序终止过程中异常是怎么一步步传递的。当某个代码出现异常后,首先异常会传递给当前的代码行,如果当前代码行没有解决方案,异常会传递给调用当前异常代码的函数,看看调用有问题代码的函数内部是否有解决方案;如果还没有,则返回到主程序中,看看主程序内部是否有解决当前异常的方案,如果还没有,则报错终止程序。具体流程图如下:
主动抛出异常就是指我们可以人为去定义一些我们需要的异常,这些异常可以在配置好某些代码后符合条件的情况下自动抛出,这就是主动抛出异常。而如果我们想要这么做,我们首先要做的是定义一个异常对象。我们可以利用Exception类来创建一个异常对象,然后传递进去一个参数,这个参数就是一个异常的描述信息。定义完后,我们就可以利用关键字rasie抛出异常了。
自然,我们也可以利用其它错误的捕获异常捕获它:
- try:
- Error = Exception("Error")
- raise Error
- except Exception as get:
- print(get)