008-面向对象(模式)& 异常
2020-05-14 本文已影响0人
痞子_4ae7
工厂模式(面向对象封装练习)
- 概念
工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替传统的直接创建对象的一种模式
- 用法
非工厂模式:
公司招聘<--------------------------->学生
工厂模式:
提需求 满足条件
公司招聘<-------> 学校<----------->学生
class Company(object):
def __init__(self,name):
self.name = name
# 公司招聘方法
def recruitment(self,subject):
self.subject = subject
print(self.name+"公司需要招聘"+self.subject+"人才")
# 通过委托学校进行招聘
self.school = School()
# 招聘要求为公司的要求: subject
stu = self.school.cultivate(self.subject)
return stu
class Student():
def __init__(self):
self.skill = None
pass
class StudentPython(Student):
def __init__(self):
self.skill = 'Python'
pass
def __str__(self):
return '[' + '我擅长 Python'+']'
class StudentJava(Student):
def __init__(self):
self.skill = 'Java'
pass
def __str__(self):
return '[' + '我擅长 Java' + ']'
class School(object):
# 工厂方法:根据需求不同,返回不同的对象
def cultivate(self,requement):
self.requement = requement
if self.requement == 'python':
return StudentPython()
elif self.requement == 'java':
return StudentJava()
# 招聘公司
com = Company('中科软')
# 根据科目招聘
stu = com.recruitment('python')
print(stu)
new方法(单例模式就会用到重写new方法)
- 魔法方法
_new__,在创建对象时候,由python解释器调用,不能手动调用
- 一定要有参数
至少要有一个参数 'cls',代表要实例化的类,实际参数,在实例化时,由python解释器自动提供
- 一定要有返回值
如果要重写new方法时,要特别注意,可以return 父类__new__出来的实例,也可以直接return
object的__new__出来的实例
class AAA(object):
def __init__(self):
print("init方法")
def __new__(cls):
print("这是new方法")
# return object.__new__(cls)
return super().__new__(cls)
AAA()
执行结果:
这是new方法
init方法
- init方法
__init__方法有一个参数self,这个就是__new__方法返回的实例,__init__作用
是给对象进行初始化操作,__init__不需要返回值
单例模式
- 概念
是一种常用的软件设计模式,应用该模式的类一个类只有一个实例,即一个类只有一个对象实例。
- 用法
因为创建对象时,会默认调用__new__,以及__init__方法,所以,需要重写这两个方法完成
注意点: 对象唯一,只进行一次初始化
# 保证创建对象的唯一性,需要重写__new__方法
class SingleClass(object):
# 用来保证对象唯一
__single = None
# 用来保证初始化工作只第一次有效
__firstInit = False
def __new__(cls,name,age):
if not cls.__single:
cls.__single = super().__new__(cls)
return cls.__single
def __init__(self,name,age):
if not self.__firstInit:
self.name = name
self.age = age
self.__firstInit = True
a = SingleClass('aaa',12)
b = SingleClass('bbb',13)
# 分别查看a与b的地址
print(id(a))
print(id(b))
# 验证是否只有第一次初始化生效
print(a.age)
print(b.age)
# 验证对象值是否统一修改
a.age = 19
print(b.age)
- 作用
保障全局过程中,只使用一个对象
异常的引入
- 概念
异常就是不正常,当python检测到一个错误时,解释器就无法继续执行下去了,
反而出现了一些错误的提示,这就是所谓的异常。
捕获异常
-
try---except
案例:从键盘输入被除数与除数,求商并打印
- 传统解决方法
- 使用异常处理的解决方法
-
except 多个异常
- 多个异常分开写(注意异常<父子>类的顺序)
try: <语句> except <异常类名字>: <语句> except <异常类名字>: <语句> else: #如果没有异常发生 <语句>
- 多个异常写到一个元组中
try: 代码 except(Exception1[,Exception2[,...ExceptionN]]]): 发生以上多个异常中的一个,执行这块代码 ''''
-
获取异常信息
try:
f = open('124.txt', 'r')
f.write('HelloWorld')
#将捕获到的异常存储到到变量errMsg中
except IOError as errMsg:
print(errMsg)
-
捕获所有异常
- except 不带任何异常
try: a = 2/0 except: print("遇到异常")
- except 父类Exception
try: b = 3/0 except BaseException as result: print(result)
-
捕获异常中else的用法
try:
b = 3/1
except BaseException as result:
print(result)
else:
# 可以访问b的值
print("没有遇到异常,结果为:%d"%b)
-
try--- finally
finally顾名思义: 最终,最后的意思- 用处
确保最后一定要执行的,比如:文件关闭、数据库关闭、socket关闭,等...
- 案例:(文件关闭问题)
try: f = open('123.txt', 'r') # 如果遇到异常,后续代码不再执行,直接执行except模块 f.write('HelloWorld') # 在这关闭文件是否合适 f.close() except IOError as errMsg: print(errMsg) else: print("写入文件成功") finally: # 最终一定要关闭文件(打印,验证是否执行) f.close() print("finally,文件关闭")
异常的传递
- 案例
def test1(): print("-" * 10 + "test1开始" + "-" * 10) print(aa) print("-" * 10 + "test1结束" + "-" * 10) def test2(): print("-" * 10 + "test2开始" + "-" * 10) test1() print("-" * 10 + "test2结束" + "-" * 10) def test3(): print("-" * 10 + "test3开始" + "-" * 10) try: test2() except: pass print("-" * 10 + "test3结束" + "-" * 10) test3()
抛出自定义异常
- 自定义异常
通过创建一个新的异常类,程序可以命名它们自己的异常。
异常应该是典型的继承自Exception类,通过直接或间接的方式
# 自定义异常类,直接或者间接继承Exception
class GenderException(Exception):
def __init__(self):
super().__init__()
# args 为BaseException的属性
self.args = '性别只能为男或者女'
# 也可以自定义一个属性
self.msg = '性别只能为男或者女'
- 手动抛出自定义异常
语法: raise [Exception [, args [, traceback]]]
class Student(object):
def __init__(self, name, gender, age):
self.__name = name
self.setGender(gender)
self.__age = age
def setGender(self, gender):
if gender == '男' or gender == '女':
self.__gender = gender
else:
# 抛出一个自定义的性别异常(也可以以列表的形式抛出多个异常)
# raise [GenderException(), Exception()]
raise GenderException()
try:
stu1 = Student('大黄', '男1', 18)
except GenderException as e:
# 打印自定义的信息
print(e.msg)
# 打印父类属性的信息
print(e.args)