python面向对象
2019-06-01
--张伯羽
1.单例模式
单例模式的主要目的是确保某一个类只有一个实例存在
- 例子:
class DB:
instance = None
def __new__(cls, *args, **kwargs):
if DB.instance is None:
DB.instance = super().__new__(cls)
return DB.instance
# 每次都只会生成一个实例
2.MVC:模型——视图——控制器 框架
- 模型(Model)
模型是核心部分,包含和管理业务逻辑、数据、状态和应用规则,模型执行所有的状态改变和必要的校验,并告诉控制器该做什么
- 视图
视图不负责处理数据,只展示数据,是数据可视化的表现,窗口、pdf文档、应用图形界面等都是视图
- 控制器
控制器控制视图和模型的通信,与模型交互,按照模型的指令控制视图
3.观察者设计模式
又名:发布-订阅模式、模型-视图模式、源-监听器模式以及从属者模式
- 借鉴一些人的说法,在打游戏时,你捡到了一把AWM,接着便向队友喊话炫耀,这时与你连麦的队友都能听到你的喊话并跑过来把你打死,再抢走那把AWM......
- 又例如,当订阅者订阅了某系列杂志,当杂志有了新的状态,比如更新了,那么此时就会给所有的订阅者发送一条消息,那么所有的订阅者就会收到此消息做出购买或不购买的选择。
- 或是产品中介会联系卖家和买家,向卖家和买家提供最新消息。
-
Subject(观察者集合)
class Subject:
def __init__(self):
self.observers = []
def add_observer(self, observer):
self.observers.append(observer)
return self
def remove_observer(self, observer):
self.observers.remove(observer)
def notify(self, msg):
for observer in self.observers:
observer.update(msg)
Subject可以包含多个观察者对象并对这些观察者进行管理,比如添加add_oberver(...)、移除remove_observer(...)和发送通知给所有观察者notify(...)
2.Observer(抽象观察者)
包含观察者应该具有的属性和接受信息(更新数据)的方法,观察者对观察目标的变化做出反应
3.ConcreteSubject(目标状态)
它改变时便会通知观察者集合
4.ConcreteObserver(具体观察者)
具体观察者中会维护一个指向具体目标对象的引用,它存储了具体观察者的状态,这些状态和具体目标的状态要保持一致。
它实现了抽象观察者对象的updata方法,并且可以把自己加入到观察者集合中
class Observer:
def __init__(self, name):
self.name = name
def update(self, msg):
print(self.name + "收到信息" + msg)
- 例子
xiaoming = Observer("xiaoming")
lihua = Observer("lihua")
rain = Subject()
rain.add_observer(xiaoming).add_observer(lihua)
rain.notify("xswl")
xiaoming收到信息xswl
lihua收到信息xswl
4.异常处理
- 获得原谅比请求许可跟容易
- 异常发生后,程序就结束了
opt = int(input("请输入一个整数"))
print(opt)
# 输入‘d’异常
请输入一个整数d
Traceback (most recent call last):
File "C:/Users/admin/PycharmProjects/监控/异常处理.py", line 11, in
opt = int(input("请输入一个整数"))
ValueError: invalid literal for int() with base 10: 'd'
-
用try语句
# try:
# 可能发生异常的代码
# except:
# 异常处理代码
- except:处理所有异常
- except Type: 处理指定类型的异常
- except Type as data: 获取异常信息
- except (Type1, Type2, Type3): 同时处理这三种异常,如果想获得异常数据,同样可以使用as语句
# 输入‘d’异常
请输入一个整数d
Traceback (most recent call last):
File "C:/Users/admin/PycharmProjects/监控/异常处理.py", line 30, in
你输入的不是一个数
# try:
# pass
# except 异常类型1:
# pass
# except 异常类型2:
# pass
# except (异常类型3, 异常类型4, 异常类型5):
# pass
# except Exception as e:
# print(e)
# 定义这种方式捕捉异常时,一定要先写具体的异常,再写具有普遍性的异常,所有的异常,继承自Exception
-
else、finally
else是没有发生异常时执行
finally最终都会执行
# try:
# pass
# except(valueError, KeyError):
# 发生异常时执行
# else:
# 没有发生异常时执行
# finally:
# 有没有异常都会执行(一般用来释放资源)
# try:
# print("zs")
# finally:
# print("finally")
try:
num = int(input("请输入整数"))
result = 8/num
print(result)
except ValueError:
print("请输入一个整数")
except ZeroDivisionError:
print("除数不能为0")
except Exception as e:
print("未知错误%s"% e)
else:
print("执行正常")
finally:
print("执行完成")
- 输入不是整数异常:
# 输入‘d’
请输入整数d
请输入一个整数
执行完成
- 输入除数为0:
# 输入除数为0
请输入整数0
除数不能为0
执行完成
- 无异常:
请输入整数3
2.6666666666666665
执行正常
执行完成
-
异常的传递
异常发生后,会传递给方法(函数)的调用者A,如果A捕捉到该异常,则按捕捉机制处理,如果A没有捕捉该异常,则会层层向上传递
最终会传递到python解析器,就简单地中止程序
def fun1():
a = 0
print(10/a)
def fun2():
try:
fun1()
except ZeroDivisionError:
print("除数为0")
fun2()
除数为0
-
手动抛出异常:raise
def fun3():
print("hello")
raise ZeroDivisionError()
fun3()
Traceback (most recent call last):
File "C:/Users/admin/PycharmProjects/监控/异常处理.py", line 90, in
fun3()
hello
File "C:/Users/admin/PycharmProjects/监控/异常处理.py", line 89, in fun3
raise ZeroDivisionError()
ZeroDivisionError
-
自定义异常(简化程序)
将不符合条件的作为异常丢掉,从而简化程序
如下例中“zhan”不符合用户名条件,故执行异常操作
class ParamInvalidException(Exception):# 继承Exception类
def __init__(self, code, msg):
self.code = code
self.msg = msg
def login(username, pwd):
if len(username) < 6:
raise ParamInvalidException(2001, "用户名长度在1~6之间")
if username != "zhangsan":
raise ParamInvalidException(2002, "用户名错误")
print("登录成功")
try:
# “zhan”不符合用户名条件,故执行异常操作
login("zhan", "12345")
print("后继操作")
except ParamInvalidException as e:
print(e.code, e.msg)
2001 用户名长度在1~6之间
-
程序发生异常该怎么办
首先判断是否是可控的,不可控就不管,可控异常进行处理,不管是不是可控的,都先记录一下
try:
pass
except Exception:
先记录异常
能处理就处理
不能处理:raise
5.字符问题
- 如何表示字符: map 65 -> a 66 -> b :ASCII 一个字符占:8 bit: 2^8 -> 256 => 127
- GB2312 # GBK (等长编码)
- Unicode 编码 16 2^6 (等长编码)
- UTF-8(不等长\变长编码)
bytes = '张三'.encode("GBK")
print(bytes)
print(type(bytes))
byte_utf8 = '张三'.encode("utf-8")
print(byte_utf8)
str = bytes.decode("GBK")
print(str)
# 乱码
str = byte_utf8.decode("GBK")
print(str)
b'\xd5\xc5\xc8\xfd'
b'\xe5\xbc\xa0\xe4\xb8\x89'
张三
# 乱码
寮犱笁
6.文件操作
文本文件:
文本文件本质上存储时,也是二进制,但可以用文本编辑器查看二进制文件
二进制文件无法通过文本编辑器查看
- 以'utf=8'的编码、追加('a')方式“demo.txt”文件,并使用 .write(str)函数写入,最后用 .close()函数关闭文件
try:
f = open("D://demo.txt", 'a', encoding='utf-8')
f.write("neuedu\n")
f.write("NEUQ\n")
finally:
f.close()
- 用with就不需要.close()方法关闭文件:
with open("D://demo.txt", 'a', encoding='utf-8') as f:
f.write("neuedu\n")
f.write("NEUQ\n")
-
readline()和readlines():
with open("D://demo.txt", encoding='utf-8') as f:
# 全部读入
content = f.read()
print(content)
# 读入一行
line = f.readline()
print(line)
# 每行都读入,返回一个列表
for line in f.readlines():
print(line)
-
文件的打开模式
- r:以只读方式打开文件,文件的指针会放在文件的开头,这是默认模式,如果文件不存在,抛出异常
- w:以只写方式打开文件,如果文件存在会被覆盖,如果文件不存在,则创建新文件
- a:以追加方式打开文件,如果文件已存在,则指针会放在文件的结尾,如果文件不存在,则创建文件
- r+:以读写方式打开文件,文件的指针放在文件的开头,如果文件不存在,则抛出异常
- w+:以读写方式打开文件,如果文件存在,会被覆盖,如果不存在,则创建文件
- a+:以读写方式打开文件,如果文件存在,则指针在文件的末尾,如果不存在,则创建文件