|
继续小结py的面向对象,本篇聊聊单例设计模式和异常的处理。
一、单例,即用类创建的实例对象始终只有一个唯一的实例(指向同一内存地址),这在设计如音乐播放器、回收站等程序时有这种需求。
py的单例写法是基本固定的(用时可以照搬),要说清单例,先得说说类创建实例对象的过程。
py在用类名()这种方法创建实例对象时,实际上先调用一个内置方法__new__,作用是为对象分配内存空间,再将内存的引用地址返回给__init__初始化方法的self,进行对象的初始化。要实现单例,就要重写__new__方法,使每次调用__new__方法时始终返回第一次分配的内存空间地址,其次是让__init__初始化方法只执行一次。
要达到这个目的,需要定义两个类属性,一个用于判断是否已经分配了内存空间(是否有了内存的引用地址),一个判断是否进行了初始化;还需要重写__new__方法。下面举个音乐播放器的例子(如果不理解,以后可以照搬)
class MusicPlayer(object):
# 定义类属性instance,记录第一个被创建对象的引用,None代表空对象
instance = None
# 定义类属性init_flag,记录是否执行过初始化动作
init_flag = False
# 重写__new__方法
def __new__(cls, *args, **kwargs):
# 1. 判断类属性instance是否是空对象
if cls.instance is None:
# 2. 调用父类的方法,为第一个对象分配空间
cls.instance = super().__new__(cls)
# 3. 如果非空对象,直接返回类属性保存的对象引用
return cls.instance
# __init__方法中判断是否进行过初始化
def __init__(self):
if not MusicPlayer.init_flag:
print("初始化音乐播放器")
MusicPlayer.init_flag = True
# 创建多个对象,输出对象,进行测试
player1 = MusicPlayer()
print(player1)
player2 = MusicPlayer()
print(player2)
二、异常处理
所谓异常,即指程序运行时发生错误,我们知道,程序一旦出错会导致程序执行终止。所谓异常处理,就是想办法捕获异常,然后按程序员的意愿去处理异常。
抛出异常分自动和被动,先说说一般意义上的异常处理,完整的异常处理代码如下:
try:
# 尝试执行的代码
pass
except 错误类型1:
# 针对错误类型1,对应的代码处理
pass
except 错误类型2:
# 针对错误类型2,对应的代码处理
pass
except (错误类型3, 错误类型4):
# 针对错误类型3 和 4,对应的代码处理
pass
except Exception as result:
# 打印错误信息
print(result)
else:
# 没有异常才会执行的代码
pass
finally:
# 无论是否有异常,都会执行的代码
print("无论是否有异常,都会执行的代码")
——这里错误类型指 Python 解释器 抛出异常 时,最后一行错误信息的第一个单词,就是错误类型。
关于异常处理,还需要了解异常的传递,当函数/方法执行出现异常,会将异常传递给函数/方法的调用一方,只有传递到主程序,仍然没有异常处理,程序才会被终止。因此,在开发中,可以在主函数中增加异常捕获,即在主函数中调用的其他函数,只要出现异常,都会传递到主函数的异常捕获中,这样就不需要在代码中,增加大量的 异常捕获,能够保证代码的整洁。
自动抛出异常,应用场景:在开发中,除了 代码执行出错 Python 解释器会 抛出 异常之外,还可以根据应用程序特有的业务需求主动抛出异常,如提示用户输入密码,如果长度少于 8,抛出异常(需要其他的函数进行额外处理)
Python 中提供了一个 Exception 异常类(js有Error对象),如果希望抛出异常,可以:
创建 一个 Exception 的对象
使用 raise 关键字 抛出 异常对象,如
def input_password():
# 1. 提示用户输入密码
pwd = input("请输入密码:")
# 2. 判断密码长度,如果长度 >= 8,返回用户输入的密码
if len(pwd) >= 8:
return pwd
# 3. 如果密码长度不够,需要抛出异常
# 1> 创建异常对象 - 使用异常的错误信息字符串作为参数
ex = Exception("密码长度不够")
# 2> 抛出异常对象
raise ex
try:
user_pwd = input_password()
print(user_pwd)
except Exception as result:
print("发现错误:%s" % result)
关于单例和异常处理小结到此,以后遇到单例这种需求可以直接套用,至于异常处理,体会不深,记得学js时,提到过一个观点,“能用if解决的问题就不用异常处理”,不知道在py中是否同样如此,不过想想也是,如果一个错误可以预见,感觉用if处理要好些。。。 |