单例模式就是告诉你,只有一个对象

(1)单例模式不适用的场景

#单例模式就是告诉你,其实只有一个对象
class Person:
def __init__(self,name,age):
self.name = name
self.age = age '''
假设这样一个场景,有一个专门创造人的这样一个类,在我们每实例化创造一个人的时候,
我们要赋予这个人姓名,年龄,基本,身高,等等,这种模式明显不适用单例模式,因为有多个对象,
且每个对象都封装了不同属性,单例模式则只能允许创建一个人,所以不适用
'''
xiaoming=Person('小明',18)
xiaoyue =Person('小月',19)
xiaohong = Person('小红',28)

(2)当所有实例中封装的数据相同时,就可以使用单例模式,例如

class Person2:
def __init__(self):
self.name = 'jay'
self.age = 33
def f1(self):
pass
def f2(self):
pass xiaoming =Person2()
xiaoming.f1()
'''创建了两个相同的实例,浪费内存,这种情景可以使用单例模式了'''
xiaoming = Person2()
xiaoming.f1()

还有一个经典的使用场景,机器之间数据库的链接

下面对这种单例模式进行探讨,假设创建一个连接池

import random
class ConnectionPool:
def __init__(self):#链接数据库需要的通行证
self.ip= '2.2.2.2'
self.port= 6379
self.pwd = '654321'
self.username = 'jay'
#去链接
self.conn_list = [1,2,3,4,5,6]#假设创建了6个链接
def get_connection(self):
#获取链接,这里具体每写,只是个例子
r = random.randrange(1,6)
return r pool=ConnectionPool()
for i in range(6):
  conn = pool.get_connection()#进行链接,每次链接的时候进去拿一个连接就好了,不用再实例化一个对象

 这样个人每次在操作的时候都是一个单例模式,用一个实例进行链接,但是如果多个人同事打开这个文件,还是会实例化多个同样的对象,浪费内存

我们可以这样操作,使在内存里面每次调用的时候都似乎获取到第一次创建的实例

import random
class ConnectionPool:
__instance = None#默认是None
def __init__(self):#链接数据库需要的通行证
self.ip= '2.2.2.2'
self.port= 6379
self.pwd = '654321'
self.username = 'jay'
#去链接
self.conn_list = [1,2,3,4,5,6]#假设创建了6个链接
@staticmethod
def get_instance():
if ConnectionPool.__instance:#如果实例已经存在,则直接返回创建过的实例
return ConnectionPool.__instance
else:
ConnectionPool.__instance =ConnectionPool()#如果是第一次调用,执行该函数,实例化一个连接池
return ConnectionPool.__instance#将对象赋值给静态字段
def get_connection(self):
#获取链接
r = random.randrange(1,6)
return r obj1= ConnectionPool.get_instance()
print(obj1)
obj2= ConnectionPool.get_instance()
print(obj2)
obj3= ConnectionPool.get_instance()
print(obj3)
obj4= ConnectionPool.get_instance()
print(obj4)

  结果如图

(3)创建web站点的单例模式

这里是用简单的Python代码写一个网站

from wsgiref.simple_server import make_server

def index():
return 'index'
def news():
return 'nnnnnnn'
def RunSever(environ,start_response):
start_response(status='200 ok',headers=[('Content-Type','text/html')])
url=environ['PATH_INFO']#这是用户访问的url
#这里我们访问http://127.0.0.1:8000/ if url.endswith('index'):#根据网页以什么什么结尾则决定调用的函数
return index() elif url.endswith('news'):
return news()
else:
return '404'
'''
这里表示的是当我们访问http://127.0.0.1:8000/index,则返回index函数的执行结果,其他同理
这里相当于搞了个网站
''' if __name__ == '__main__': httpd= make_server('',8000,RunSever)#相当于启动一个网站,8000在这里表示端口
print('Server HTTP on port 8008...')
httpd.serve_forever()#一直监听该端口,内部有个while循环,等待别人访问

  当我们执行的时候,浏览器打开这个这个网站,则会根据条件返回相关数据,结果如图

     

只要有人来请求了,则会在内存里面执行一次RunSever函数,给请求人结果,

当我们把上面那个ConnectionPool类的代码加进这个web站点里面,可以使用单例模式,使访问的用户每次只调用同一个实例

from wsgiref.simple_server import make_server
import random class ConnectionPool:
__instance = None#默认是None
def __init__(self):#链接数据库需要的通行证
self.ip= '2.2.2.2'
self.port= 6379
self.pwd = '654321'
self.username = 'jay'
#去链接
self.conn_list = [1,2,3,4,5,6]#假设创建了6个链接
@staticmethod
def get_instance():
if ConnectionPool.__instance:#如果实例已经存在,则直接返回创建过的实例
return ConnectionPool.__instance
else:
ConnectionPool.__instance =ConnectionPool()#如果是第一次调用,执行该函数,实例化一个连接池
return ConnectionPool.__instance#将对象赋值给静态字段
def get_connection(self):
#获取链接
r = random.randrange(1,6)
return r def index():
p = ConnectionPool.get_instance()
print(p) # 这里使每次用户访问的时候都调用同一个类,节约内存,之后则可以调用ConnectionPool的方法,例如选取链接
return 'index'
def news():
return 'nnnnnnn'
def RunSever(environ,start_response):
start_response(status='200 ok',headers=[('Content-Type','text/html')])
url=environ['PATH_INFO']#这是用户访问的url
#这里我们访问http://127.0.0.1:8000 if url.endswith('index'):#根据网页以什么什么结尾则决定调用的函数
return index() elif url.endswith('news'):
return news()
else:
return '404'
'''
这里表示的是当我们访问http://127.0.0.1:8000/index,则返回index函数的执行结果,其他同理
这里相当于搞了个网站
''' if __name__ == '__main__': httpd= make_server('',8000,RunSever)#相当于启动一个网站,8000在这里表示端口
print('Server HTTP on port 8008...')
httpd.serve_forever()#一直监听该端口,内部有个while循环,等待别人访问

  这样,每次就算不同的人访问该页面,都是调用同一个类的方法,可以节约服务器内存

结果如图,都是同一个内存

最新文章

  1. WIN-CE系统架构
  2. poj2676 Sudoku
  3. oracle 配置
  4. MYSQL中约束及修改数据表
  5. poj3372 Candy Distribution
  6. 如何用 Parse 和 Swift 搭建一个像 Instagram 那样的应用?(2)
  7. iOS中Git的使用
  8. python高级编程之最佳实践,描述符与属性01
  9. 左右db_block_size了解和实验
  10. 关于java socket(转)
  11. linux_曝出重大bash安全漏洞及修复方法
  12. Ubuntu 14 安装MySQL指南
  13. Mysql安装、设置密码、编码
  14. Python基础教程2#练习使用参数的疑难杂点分析
  15. redis 启动停止脚本
  16. hdu5029 树链剖分 + 线段树
  17. poj 3984 -- 迷宫问题 深搜
  18. ubuntu初次设置root密码
  19. mybatis之 # 与 $ 区别以及 sql 预编译
  20. java instanceof和isInstance的关系 精析

热门文章

  1. hihocoder第三十六周 二分查找
  2. Hybris ECP里Customer对应的数据库表
  3. js高级笔录
  4. [转] 防止js全局变量污染方法总结
  5. 在docker镜像中加入环境变量
  6. 通过cmd查看环境变量名对应的环境变量值
  7. MySQL表碎片整理
  8. linux替换yum源及配置本地源
  9. Date.prototype.Format---对Date的扩展
  10. 15.VUE学习之-表单中使用key唯一令牌解决表单值混乱问题