一、设计模式
设计模式是前人的总结和经验的提炼;
通常,被人人们广为流传的设计模式都是针对某一特定问题的成熟解决方案。
二、单例设计模式
单例:让类创建的对象,在系统中有唯一的实例
创建对象的时候:
1.为对象分配空间:new()
创建对象的时候,python解释器首先会调用__new__方法为ie对象分配空间
__new__是一个由object基类提供的内置的静态方法,主要有两个作用:
在内存中为对象分配空间
返回对象的引用
2.对象初始化 :init()
python解释器获得对象的引用后,将引用的第一个参数,传递给__init__方法
class MusicPlyer(object):
def __new__(cls, *args, **kwargs):
# 第一个参数cls:哪一个类调用就传递哪一个类
# 第二个参数*args:是一个多值元组参数
# 第三个参数**kwargs:是一个多值的字典参数
# 1.创建对象时,new方法会被自动调用
print '创建对象,分配空间' # 重写了父类的方法
#2.为对象分配空间
# __new__方法是一个静态方法,在调用的时候,第一个参数是cls
instance = object.__new__(cls)
# 3.返回对象的引用
return instance
def __init__(self):
print '初始化播放器'
# 创建播放器对象
player1 = MusicPlyer()
print player1
player2 =MusicPlyer()
print player2
class MusicPlayer(object):
# 记录第一个被创建对象的应用
instance = None
def __new__(cls, *args, **kwargs):
# 判断类属性是否为空(如果是空对象,说明第一个对象还没被创建)
if cls.instance is None:
# 调用父类的方法,为第一个对象分配空间
cls.instance = object.__new__(cls)
# 返回类属性保存的对象引用
return cls.instance
# 创建多个对象
player1 = MusicPlayer()
print player1
player2 = MusicPlayer()
print player2
"""
重写__new__方法的代码非常固定:
继承自父类方法
返回父类方法调用_new__方法的结果
重写__new__方法一定要return object.__new__(cls)
否则python的解释器得不到分配了空间的对象引用,就不会调用对象的初始化方法
"""
"""
python中的单例:
单例:让类创建的对象,在系统中只有唯一的一个实例
1.定义一个类属性,初始值时None,用于记录单例对象的引用(因为当一个类定义完成运行程序的时候,
内存中有这个类创建的对象么?
并没有,我们需要调用创建对象的方法,内存中才会有第一个对象)
2.重写__new__方法
3.如果类属性is None,调用父类方法分配空间,并在类属性中记录结果
4.返回类属性中记录的对象引用
"""
只执行一次初始化工作
在每次使用 类名() 创建对象时,python的解释器都会自动调用两个方法
__new__ 分配空间
__init__ 对象初始化
但在上一小结中 __new__方法改造之后,每次都会得到第一次被创建对象的引用
但是:初始化方法还会被再次掉用
需求:让初始化方法只执行一次
解决办法:
1.定义一个类属性init_flag标记是否执行过初始化动作,初始值为false
2.在__init__方法中,判断init_flag,如果为false就执行初始化动作
3.然后将init_flag设置为trun
4.这样,再次自动调用__init__方法时,初始化动作就不会再次被执行了
"""
class MusicPlayer(object):
# 记录第一个被创建对象的应用
instance = None
init_flag = False
def __new__(cls, *args, **kwargs):
# 判断类属性是否为空(如果是空对象,说明第一个对象还没被创建)
if cls.instance is None:
# 调用父类的方法,为第一个对象分配空间
cls.instance = object.__new__(cls)
# 返回类属性保存的对象引用
return cls.instance
def __init__(self):
# 1.判断是否执行过初始化方法
if MusicPlayer.init_flag:
return
# 2.如果没有执行,执行初始化动作
print '初始化播放器'
# 3.修改类属性的标记
MusicPlayer.init_flag = True
# 创建多个对象
player1 = MusicPlayer()
print player1
player2 = MusicPlayer()
print player2
二、异常
1、概念
异常:
程序在运行的时候,如果python解释器遇到一个错误,会停止程序的执 行,并且提示一些错误的信息,这就是异常
我们在程序开发的时候,很难将所有的特殊情况都处理,通过异常捕获可以针对突发事件做集中处理,从而保证程序的健壮性和稳定性
2、简单捕获异常的语法
在程序开发中,如果对某些代码的执行不能确定(程序语法完全正确)可以增加try来捕获异常
try:
尝试执行的代码
except:
出现错误的类型
try:
# 不能确定正确执行的代码
num = int(raw_input('请输入一个整数:'))
except:
print '重新输入'
print '*' * 50
3、练习
需求:
1.提示用户输入一个整数
2.使用8除以用户输入的整数并输出
根据错误类型来捕获异常
try:
尝试执行的代码
except 错误类型1:
针对错误类型1,对应的代码处理
except 错误类型2:
针对错误类型2,对应的代码处理
1、所有的异常都列举完时
try:
# 提示用户输入一个整数
num = int(raw_input('输入一个整数:'))
# 使用8除以整数并且输出
result = 8 / num
print result
except ZeroDivisionError:
print '0不能做除数'
except ValueError:
print '输入的值不是数字'
"""
1.0不能做除数
2.输入的值不是数字
"""
print '* ' * 50
2、无法枚举完所有异常的情况时
try:
# 提示用户输入一个整数
num = int(raw_input('输入一个整数:'))
# 使用8除以整数并且输出
result = 8 / num
print result
# except ZeroDivisionError:
# print '0不能做除数'
except ValueError:
print '输入的值不是数字'
# 没有预先判断到的错误,但是如果出现,我们也不希望程序以外停止
except Exception as result:
print '未知错误 %s' % result
finally:
# 无论是否有异常,都会执行的代码
print '无论是否有异常,都会执行的代码'
4、异常的传递
def demo1():
return int(raw_input('输入整数:'))
def demo2():
return demo1()
# 函数的错误:一级一级的去找,最终会将异常传递到主程序里面
# print demo2()
try:
print demo2()
except Exception as result:
print '未知错误 %s' % result
5、抛出异常
需求:提示用户输入密码,如果长度小于8,就抛出异常
def input_passwd():
# 1.提示用户输入密码
pwd = raw_input('请输入密码:')
# 2.判断密码的长度 >=8,返回用户的密码
if len(pwd) >= 8:
return pwd
# 3.如果<8 主动抛出异常
print '主动抛出异常'
# 1.创建异常对象
ex = Exception('密码长度不够')
# 2.主动抛出异常
raise ex
# 注意:只抛出异常而不捕获异常,代码会出错
try:
print input_passwd()
except Exception as result:
print result
6、断言
可以理解为提前预言,让人更好的知道错误的原因
def func(num, div):
assert (div != 0),'div不能为0'
return num / div
print func(10,0)