python第六天学习

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......
  • 又例如,当订阅者订阅了某系列杂志,当杂志有了新的状态,比如更新了,那么此时就会给所有的订阅者发送一条消息,那么所有的订阅者就会收到此消息做出购买或不购买的选择。
  • 或是产品中介会联系卖家和买家,向卖家和买家提供最新消息。
  1. 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:
#     异常处理代码
  1. except:处理所有异常
  2. except Type: 处理指定类型的异常
  3. except Type as data: 获取异常信息
  4. 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("执行完成")
  1. 输入不是整数异常:
# 输入‘d’
请输入整数d
请输入一个整数
执行完成
  1. 输入除数为0:
# 输入除数为0
请输入整数0
除数不能为0
执行完成
  1. 无异常:
请输入整数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.文件操作

  1. 文本文件:
    文本文件本质上存储时,也是二进制,但可以用文本编辑器查看

  2. 二进制文件
    二进制文件无法通过文本编辑器查看

  • 以'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+:以读写方式打开文件,如果文件存在,则指针在文件的末尾,如果不存在,则创建文件

你可能感兴趣的:(python第六天学习)