一、单列模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。

如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 Config 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 Config 对象的实例,这就导致系统中存在多个 Config 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 Config 这样的类,我们希望在程序运行期间只存在一个实例对象。

二、装饰器实现单列模式

通过python的闭包原理,装饰器能记得外层命名空间装饰器原理参考本文

def single_decorator(cls):
single = {}
def wrapper(*args, **kwargs):
if not single.get(cls.__name__):
single[cls.__name__] = cls(*args, **kwargs)
return single[cls.__name__]
return wrapper @single_decorator
class School:
def __init__(self, name, addr, capital, represent):
self.__name = name #学校名
self.__addr = addr #地址
self.__registered_capital = capital #注册资金
self.__represent = represent #法人代表 def get_info(self):
return "校名: {} 地址: {} 法人代表: {}".format(self.__name, self.__addr, self.__represent) @staticmethod
def show():
print(School._isxx) ss= School('古天乐学校', '大凉山', '100.000', '古天乐')
ss2= School('施明德', '台湾?', '1.000.000', '瞎写的')
print('实例一id: %s'%(id(ss)))
print('实例二id: %s'%(id(ss2)))
print(ss.get_info())
print(ss2.get_info()) #运行结果为:
实例一id: 397109139440
实例二id: 397109139440
校名: 古天乐学校 地址: 大凉山 法人代表: 古天乐
校名: 古天乐学校 地址: 大凉山 法人代表: 古天乐

这样就可以将这个装饰器装饰到任何一个类上,完成单列了

 

三、__new__方法+静态字段实现单列模式
class Single:
_single = None
def __init__(self, value):
self.v = value
print(self.v) def __new__(cls, *args, **kwargs):
if Single._single:
return Single._single
else:
Single._single = super(Single, cls).__new__(cls)
print("只执行一次")
return Single._single s2 = Single(2)
s3 = Single(3)
s4 = Single(4) print(id(s2))
print(id(s3))
print(id(s4)) #输出结果为
只执行一次
2
3
4
s2的id为: 278042421064
s3的id为: 278042421064
s4的id为: 278042421064
  • 和类方法相类似,可以看见,s2/s3/s4 都是同一个id 是同一个实例,尽管实例时传入的值不一样
四、静态方法+静态字段实现单列模式

平时我们在链接数据库时,一个程序,也是只需要一个链接就够了,我们不希望一个程序产生很多实例去连接到数据库,这样每个链接都操作数据库,不但浪费了内存空间,还可能导致数据修改混乱

class Sqlpool:
__single = None #创建一个静态字段
def __init__(self):
#封装数据库链接需要的信息
self.ip = "192.168.1.1"
self.port = 3306
self.pwd = "1234567"
self.username = "xxxxxx" #链接数据库
self.connect = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] #假如创建了9个链接数据库的线 @staticmethod
def produce():
if Sqlpool.__single: #判断静态字段是否有值
return Sqlpool.__single #如果有值返回静态字段的值
else:
Sqlpool.__single = Sqlpool() #没有就实例一个对象给他
return Sqlpool.__single #将实例返回 #这样,无论创建多少个访问,对象时,都是一个对象,这样不会占用内存
conn1 = Sqlpool.produce() #创建一个访问对象
conn2 = Sqlpool.produce() #创建二个访问对象

原理都差不多。这个没有装饰器好用

五、类/类方法直接实现
class Singleton(object):

    def __init__(self):
pass @classmethod
def get(cls, *args, **kwargs):
if not hasattr(Singleton, "_single"):
Singleton._single = Singleton(*args, **kwargs)
return Singleton._single

类方法这儿实现单列模式还有优化,就不多说了,是多线程问题。

这儿本身原理和静态方法差不多。

单列模式,装饰器、new方法、类/静态方法实现单列模式的更多相关文章

  1. 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法

    第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一.    案例说明 本节定义了类Sta ...

  2. 第7.17节 Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析

    第7.17节  Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析 静态方法也是通过类定义的一种方法,一般将不需要访问类属性但是类需要具有的一些能力可以静态方法提供. 一 ...

  3. python装饰器2:类装饰器

    装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 本文是装饰器相关内容的第二篇,关于类装饰器. "类装饰器"有两种解读方式:用来装饰类的装饰器:类作为装饰器装饰其它东西.你 ...

  4. 类装饰器,元类,垃圾回收GC,内建属性、内建方法,集合,functools模块,常见模块

    '''''''''类装饰器'''class Test(): def __init__(self,func): print('---初始化---') print('func name is %s'%fu ...

  5. Python装饰器实现几类验证功能做法

    最近新需求来了,要给系统增加几个资源权限.尽量减少代码的改动和程序的复杂程度.所以还是使用装饰器比较科学 之前用了一些登录验证的现成装饰器模块.然后仿写一些用户管理部分的权限装饰器.比如下面这种 de ...

  6. Decorator模式 装饰器模式

    Android 使用了装饰器模式 1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法,或者须要给方法添加 ...

  7. Python类中的装饰器在当前类中的声明与调用

    [本文出自天外归云的博客园] 我的Python环境:3.7 在Python类里声明一个装饰器,并在这个类里调用这个装饰器.代码如下: class Test(): xx = False def __in ...

  8. Python之路(第二十八篇) 面向对象进阶:类的装饰器、元类

    一.类的装饰器 类作为一个对象,也可以被装饰. 例子 def wrap(obj): print("装饰器-----") obj.x = 1 obj.y = 3 obj.z = 5 ...

  9. Python装饰器实现几类验证功能做法(续)

    :昨天聊了一下构造.今天试了一下.感觉昨天聊的还是不够细化.今天结合代码实现,加以一点补充. 首先观察下面这个例子 from functools import wrapsdef decorator(f ...

随机推荐

  1. window.location.href刷新页面

    刷新当前页 window.location.href=window.location.href; 或者 window.location.href="当前URL",例如 window ...

  2. 第七章 LED将为我闪烁:控制发光二级管

    LED驱动开发实验 如图所示,LED1-LED2 分别与GPC0_3.GPC0_4 相连,通过GPC0_3.GPC0_4 引脚的高低电平来控制三极管的导通性,从而控制LED 的亮灭. 根据三极管的特性 ...

  3. shell编程/字库裁剪(1)——想法

    版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/7679024.html 作者:窗户 Q ...

  4. 如何指定一个计划和目标——6W

    作为一名IT人员,需要自己指定一个计划和目标,来保证完成进度和高效的完成任务. 参考管理学如何制作计划和目标的,套用过来,也是同样适用的.来先看看管理学的相关知识吧. 计划的概念:计划是为实现组织目标 ...

  5. 【FJWC 2019】min

    [FJWC 2019]min 题目描述 给你一张 \(n\) 个点 \(m\) 条边的无向图,走过每条边都需要花费 \(1\) 秒. 给你一个整数 \(k\) ,请你选择至多 \(k\) 个点,令经过 ...

  6. Mysql 数据库设置三大范式 数据库五大约束 数据库基础配置

    数据库设置三大范式 1.第一范式(确保每列保持原子性) 第一范式是最基本的范式.如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库满足第一范式. 第一范式的合理遵循需要根据系统给的实际需求 ...

  7. UVA11694-Gokigen Naname(DFS进阶)

    Problem UVA11694-Gokigen Naname Accept: 76   Submit: 586Time Limit: 10000 mSec Problem Description I ...

  8. 【ES6】函数

    函数默认值问题 在ES6之前,不能直接为函数指定默认值,但是ES6允许为函数的参数设置默认值 之前实现方式 function log(x, y) { y = y || 'World'; console ...

  9. ②---Java开发工具Eclipse安装配置

    Java开发工具Eclipse安装及配置 以下将为大家介绍Java开发工具Eclipse安装及配置. 一.下载Eclipse安装文件 正所谓工欲善其事必先利其器,我们在开发java语言过程中同样需要依 ...

  10. (三)JavaScript 语法

    字符串(String)字面量 可以使用单引号或双引号: "John Doe" 'John Doe' 数组(Array)字面量 定义一个数组: [40, 100, 1, 5, 25, ...