设计模式---单例模式

简介

  单例模式(Singleton Pattern) 是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实
例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
单例模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建
'''
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
'''
关键实现思想:
第一次创建类的对象的时候判断系统是否已经有这个单例,如果有则返回,如果没有则创建。那么后续再次
创建该类的实例的时候,因为已经创建过一次了,就不能再创建新的实例了,否则就不是单例啦,直接返回前
面返回的实例即可。

单例模式的python实现

使用“装饰器”来实现单例模式

  def Singleton(cls):  # 这是一个函数,目的是要实现一个“装饰器”,而且是对类型的装饰器
'''
cls:表示一个类名,即所要设计的单例类名称,
因为python一切皆对象,故而类名同样可以作为参数传递
'''
instance = {} def singleton(*args, **kargs):
if cls not in instance:
instance[cls] = cls(*args, **kargs) # 如果没有cls这个类,则创建,并且将这个cls所创建的实例,保存在一个字典中
return instance[cls] return singleton @Singleton
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age s1 = Student('张三', 23)
s2 = Student('李四', 24)
print((s1 == s2))
print(s1 is s2)
print(id(s1), id(s2), sep=' ') 运行结果:
True
True
24171496 24171496

通过__new__函数去实现

  若要得到当前类的实例,应在当前类__new__()中调用其父类的__new__()来返回,python2和python3调
用父类的__new__()方法不同:
python2: object.__new__(cls)
python3: super().__new__(cls) #super()中类可加可不加
'''基于python3代码:'''
class Student(object):
instance = None def __new__(cls, name, age):
if not cls.instance:
cls.instance = super(Student, cls).__new__(cls)
return cls.instance def __init__(self, name, age):
self.name = name
self.age = age s1 = Student('张三', 23)
s2 = Student('李四', 24)
print((s1 == s2))
print(s1 is s2)
print(id(s1), id(s2), sep=' ') 运行结果:
True
True
27579152 27579152 '''基于python2代码实现:'''
if not cls.instance:
cls.instance = object.__new__(cls)
return cls.instance

使用一个单独的模块作为单例模式

  因为,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入
时,就会直接加载 .pyc 文件,而不会再次执行模块代码。
因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做: 在一个模块中定义一个普通的类,如在demo.py模块中定义如下代码
#demo.py
class Student:
def __init__(self,name,age):
self.name=name
self.age=age student=Student('张三',23) 这里的student就是一个单例。 当我们在另外一个模块中导入student这个对象时,因为它只被导入了一
次,所以总是同一个实例。
#test.py
from demo import student
#此时,无论该test脚本怎么运行,import进来的student实例是唯一的

pickle模块

pickle模块的介绍

  (1)pickle模块:

         pickle模块是python语言的一个系统内置模块,安装python后已包含pickle库,不需要单独再安装。

  (2)pickle模块的特点:

        1、只能在python中使用,只支持python的基本数据类型,是python独有的模块。

        2、序列化的时候,只是序列化了整个序列对象,而不是内存地址。

        3、pickle有两类主要的接口,即序列化和反序列化;

       通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储;

       通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。

(3)为什么需要序列化和反序列化操作呢?

      1、便于存储

  序列化过程是将Python程序运行中得到了一些字符串、列表、字典等数据信息转变为二进制数据流。这样信息
就容易存储在硬盘之中,当需要读取文件的时候,从硬盘中读取数据,然后再将其反序列化便可以得到原始的数据。 2、便于传输 当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的
形式在网络上传送。发送方需要把对象转换为字节序列,在网络上传输;接收方则需要把字节序列在恢复为
对象,得到原始的数据。

pickle模块的使用

序列化操作

  序列化方法1:pickle.dump()
格式为:pickle.dump(obj,file)
该方法是将序列化后的对象obj以二进制形式写入文件file中,进行保存,不能直接预览。 关于文件file,
必须是以二进制的形式进行操作(写入)。 示例如下:将五个学生的成绩写入到成绩表中,保存在cjb.txt文件中
import random
import pickle # 初始化成绩表为空
cjb = [] # 写入5个学生的数据到成绩表中
for i in range(5):
name = input("name:") # 姓名
cj = random.randint(50, 100) # 随机生成50——100之间的整数作为成绩
cjb.append([name, cj])
print(cjb) # 将成绩表中的数据保存到cjb.txt文件中
with open('cjb.txt', 'wb') as f:
pickle.dump(cjb, f)
print("结果已保存")
  序列化方法2:pickle.dumps()
格式为:pickle.dumps(obj)
pickle.dumps()方法跟pickle.dump()方法不同:pickle.dumps()方法不需要写入文件中,而是
直接返回一个序列化的bytes对象。
示例如下:与上面的例子一样,只是方法不同,将五个学生的成绩写入到成绩表中,保存在cjb.txt文件中 import random
import pickle #初始化成绩表为空
cjb=[] #写入5个学生的数据到成绩表中
for i in range(5):
name=input("name:") #姓名
cj=random.randint(50,100) #成绩
cjb.append([name,cj])
print(cjb)
print(pickle.dumps(cjb)) #序列化的bytes对象
print(type(pickle.dumps(cjb))) #class 'bytes' #将成绩表中的数据保存到cjb.txt文件中
with open('cjb.txt','wb')as f:
f.write(pickle.dumps(cjb))
print("结果已保存") 运行结果为:
[['1', 66], ['2', 70], ['3', 58], ['4', 96], ['5', 63]]
b'\x80\x04\x957\x00\x00\x00\x00\x00\x00\x00]\x94(]\x94(\x8c\x011\x94KBe]\x94(\x8c\x012\x94KFe]\x94(\x8c\x013\x94K:e]\x94(\x8c\x014\x94K`e]\x94(\x8c\x015\x94K?ee.'
<class 'bytes'>
结果已保存

反序列化操作

  反序列化方法1:pickle.load()
该方法是将序列化的对象从文件file中读取出来。关于文件file,必须是以二进制的形式进行操作(读取)。
示例如下:与上面的例子一样,将五个学生的成绩写入到成绩表中,保存在cjb.txt文件中;再次运行程序
时,读取cjb.txt中的学生信息,进行加载,再次写入数据时,以追加的方式写入。
import random
import pickle #如果没有cjb,就让cjb=[],如果存在,就将内容读取出来
try:
with open('cjb.txt','rb')as f:
cjb=pickle.load(f)
print(cjb)
print("结果已加载")
except:
cjb=[]
#写入5个学生的数据到成绩表中
for i in range(5):
name=input("name:") #姓名
cj=random.randint(50,100) #成绩
cjb.append([name,cj])
print(cjb) #将成绩表中的数据保存到cjb.txt文件中
with open('cjb.txt','wb')as f:
pickle.dump(cjb,f)
print("结果已保存")
运行结果:
[['1', 66], ['2', 70], ['3', 58], ['4', 96], ['5', 63]]
结果已加载
name:11
name:22
name:33
name:44
name:55
[['1', 66], ['2', 70], ['3', 58], ['4', 96], ['5', 63], ['11', 97], ['22', 87], ['33', 50], ['44', 98], ['55', 89]]
结果已保存
  反序列化方法2:pickle.loads()
格式为:pickle.loads()
pickle.loads()方法跟pickle.load()方法不同:pickle.loads()方法是直接从bytes对象中读取
序列化的信息,而非从文件中读取。下面的例子是将信息保存到了文件中,所以要从文件中读取,以
pickle.loads(f.read())的方式读取。 示例如下:与上面的例子一样,将五个学生的成绩写入到成绩表中,保存在cjb.txt文件中;再次运行程序
时,读取cjb.txt中的学生信息,进行加载,再次写入数据时,以追加的方式写入。
import random
import pickle #如果没有cjb,就让cjb=[],如果存在,就将内容读取出来
try:
with open('cjb.txt','rb')as f:
cjb=pickle.loads(f.read())
print(cjb)
print("结果已加载")
except:
cjb=[] #写入5个学生的数据到成绩表中
for i in range(5):
name=input("name:") #姓名
cj=random.randint(50,100) #成绩
cjb.append([name,cj])
print(cjb) #将成绩表中的数据保存到cjb.txt文件中
with open('cjb.txt','wb')as f:
f.write(pickle.dumps(cjb))
print("结果已保存") 运行结果:
[['1', 87], ['2', 59], ['3', 78], ['4', 77], ['5', 75]]
结果已加载
name:a
name:b
name:c
name:d
name:e
[['1', 87], ['2', 59], ['3', 78], ['4', 77], ['5', 75], ['a', 55], ['b', 86], ['c', 86], ['d', 61], ['e', 67]]
结果已保存

选课系统项目分析

需求分析

选课系统
角色:学校、学员、课程、讲师
要求:
1. 创建北京、上海 2 所学校
2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开
3. 课程包含,周期,价格,通过学校创建课程
4. 通过学校创建班级, 班级关联课程、讲师
5. 创建学员时,选择学校,关联班级
5. 创建讲师角色时要关联学校,
6. 提供三个角色接口
6.1 学员视图, 可以登录,注册, 选择学校,选择课程,查看成绩
6.2 讲师视图, 讲师登录,选择学校,选择课程, 查看课程下学员列表 , 修改所管理的学员的成绩
6.3 管理视图,登录,注册,创建讲师, 创建班级,创建课程,创建学校
7. 上面的操作产生的数据都通过pickle序列化保存到文件里

设计分析

表示层:(向用户显示对应视图的功能)
管理员视图
学生视图
讲师视图 业务逻辑层:(主要实现功能的代码)
管理员业务:登录,注册,创建讲师, 创建班级,创建课程,创建学校
学生业务:登录,注册, 选择学校,选择课程,查看成绩
讲师业务:讲师登录,选择学校,选择课程, 查看课程下学员列表 , 修改所管理的学员的成绩 数据访问层:(对数据库的存储和取出)
存储数据

设计模式---单例模式,pickle模块的更多相关文章

  1. JavaScript设计模式-单例模式、模块模式(转载 学习中。。。。)

    (转载地址:http://technicolor.iteye.com/blog/1409656) 之前在<JavaScript小特性-面向对象>里面介绍过JavaScript面向对象的特性 ...

  2. 单例模式与pickle模块

    目录 设计模式之单例模式 pickle模块 设计模式之单例模式 设计模式是前辈们发明的经过反复验证用于解决固定问题的固定套路,在IT行业中设计模式总共有23种,可以分为三大类:创建型.结构型.行为型. ...

  3. python_way,day8 面向对象【多态、成员--字段 方法 属性、成员修饰符、特殊成员、异常处理、设计模式之单例模式、模块:isinstance、issubclass】

    python_way day8 一.面向对象三大特性: 多态 二.面向对象中的成员 字段.方法属性 三.成员修饰符 四.特殊成员 __init__.__doc__.__call__.__setitem ...

  4. Java设计模式の单例模式

    -------------------------------------------------- 目录 1.定义 2.常见的集中单例实现 a.饿汉式,线程安全 但效率比较低 b.单例模式的实现:饱 ...

  5. python模块(json和pickle模块)

    json和pickle模块,两个都是用于序列化的模块 • json模块,用于字符串与python数据类型之间的转换 • pickle模块,用于python特有类型与python数据类型之间的转换 两个 ...

  6. 【python】pickle模块

    持久性的基本思想很简单.假定有一个 Python 程序,它可能是一个管理日常待办事项的程序,您希望在多次执行这个程序之间可以保存应用程序对象(待办事项).换句话说,您希望将对象存储在磁盘上,便于以后检 ...

  7. python数据持久存储:pickle模块的基本使用

    经常遇到在Python程序运行中得到了一些字符串.列表.字典等数据,想要长久的保存下来,方便以后使用,而不是简单的放入内存中关机断电就丢失数据. 这个时候Pickle模块就派上用场了,它可以将对象转换 ...

  8. python数据持久存储:pickle模块的使用

    python的pickle模块实现了基本的数据序列和反序列化.通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储:通过pickle模块的反序列化操作,我们能够从文件 ...

  9. Python(正则 Time datatime os sys random json pickle模块)

    正则表达式: import re #导入模块名 p = re.compile(-]代表匹配0至9的任意一个数字, 所以这里的意思是对传进来的字符串进行匹配,如果这个字符串的开头第一个字符是数字,就代表 ...

随机推荐

  1. 顺利通过EMC实验(11)

  2. 浅析Node与Element

    起因 起因有二: 在看winter老师的分享:<一个前端的自我修养>时,有注意到这么一幅图,里面有写childNode和children属性. 昨天有学弟问起我,能否自己定义一个所有元素节 ...

  3. 小程序wx.getRecorderManager()录音管理

    小程序中提供了两种录音的API,wx.startRecord和wx.getRecorderManager(),前一个现在微信团队已经不再维护,所以在这里写一下新的录音管理,比之前要强大 1.小程序录音 ...

  4. Graphics 与 DisplayObject 的关系

    在原生 Canvas 中,其实并没有 DisplayObject 的概念,它只有绘制图像的概念. 大部分的原生绘制图形或图像的 API 一般是这样的: api(x, y, ...) 例如 rect 就 ...

  5. java栈stack和堆heap的工作原理,用途及区别?举例说明

    java堆和栈的区别[新手可忽略不影响继续学习] Java中内存分成两种:一种是栈stack,一种是堆heap.函数中的一些基本类型的变量(int, float)和对象的引用变量(reference) ...

  6. MySQL 中的 SQL 语句详解

    @ 目录 总结内容 1. 基本概念 2. SQL列的常用类型 3. DDL简单操作 3.1 数据库操作 3.2 表操作 4. DML操作 4.1 修改操作(UPDATE SET) 4.2 插入操作(I ...

  7. B03. BootstrapBlazor实战 10分钟编写数据库维护项目

    demo演示的是Sqlite驱动,FreeSql支持多种数据库,MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/神通/人大金仓/翰高/华为Ga ...

  8. Metaspaloit漏洞利用

    Metaspaloit介绍Metaspaloit介绍 Metasploit是一款开源的安全漏洞检测工具,可以帮助安全和IT专业人士识别安全性问题,验证漏洞的缓解措施,并管理专家驱动的安全性进行评估,提 ...

  9. docker容器编排原来这么丝滑~

    前言: 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 概念介绍: Docker Docker 这个东西所扮演的角色,容易理解,它是一个容器引擎,也就是说实际上我们的容器最终是由Docker ...

  10. Python学习进度汇报

    学习进度还是比较慢的,上周五(18号晚上安装了Pycharm)就开始学,五天只到这个位置,当前一直是2倍速看黑马的Python视频,外加查看菜鸟的文档,需要加快一些进度了,后续还有后续的目标要实现,争 ...