python的单实例模式

先看下单实例的定义

这里我们主要学习一下基于模块实现单例对象,这里利用的原理就是python的模块导入的特性,这个模块被第一次导入,会被执行一次,但是如果这个模块被再次导入,无论是在相同的文件还是在不同的文件中,第二次导入都不会再次执行

如果要想通过模块导入实现单实例模式,则必须要在一个文件中定义一个类,这里要切记,在这个文件中一定要实例化这个类,然后在其他文件中导入这个实例对象,那么所有的文件中用的实例对象都是相同的一个

比如我们看下下面的例子

在mysingle.py文件中我们定义了一个类,且实例化了这个类

class func(object):
    def foo(self):
        print("foo....")

s1 = func()

  

在main.py文件中导入两次mysingle.py文件的实例对象,这里因为导入的都是一个实例,当第一次导入的时候,mysingle.py文件就已经生成pyc文件,所以第二次导入不会在去实现mysingle.py这个文件,而是直接去pyc文件中获取实例变量,所以,我们这里打印实例对象的id,他们肯定是相同的

from mysingle import s1

from mysingle import s1 as new

print(id(s1))
print(id(new))

  

结果两个实例对象的id值当然是相同的

23991472
23991472

我们在看一个例子

我们在func.py这个文件中也导入mysingle.py这个文件的实例对象,导入文件之后,我们定义了一个函数打印导入这个实例对象的内存第一,那么func.py中打印的内存地址和main.py中打印的内存地址也是一样的

我们先看func.py这个文件

from mysingle import s1

def bar():
    print(id(s1))

  

我们在main.py文件中导入上面的func.py文件,然后在main.py文件中执行bar函数

from mysingle import s1

from mysingle import s1 as new

print(id(s1))
print(id(new))

from func import bar

bar()

  

这个时候我们打印了三个实例对象的内存地址,毫无疑问,他们的内存地址是相同的

23991472
23991472
23991472

我们看最后一个例子,前面的例子我们都是导入实例好的对象,这次我们导入mysingle.py中的类,然后在实例化这个类,我们得到的实例对象的内存地址是否相同呢,这个当然就不同了,因为每次实例化对象,都会重新开辟一个内存空间,我们前面的例子之所以不需要开辟新的内存空间,是因为我们导入的是一个实例对象

下面的例子我们就是导入类,然后实例化,我们当然可以看到,两个对象的内存地址肯定是不一样的

from mysingle import func

f1 = func()

f2 = func()

  

结果当然是不一样的,因为他们是完全不同的两个实例对象

23028752 23990736

单实例还是有其他的实现方式,这里就先不介绍了,因为我也不会,这里我们就先掌握基于模块导入实现单实例对象,这里要切记,在文件中定义一个类,然后必须要实例化这个类,同样,我们在其他位置导入的时候,则必须要导入实例对象,而不是类;实现的效果就是这个类只允许实例出来一个对象

原文地址:https://www.cnblogs.com/bainianminguo/p/9926412.html

时间: 2024-11-08 20:27:29

python的单实例模式的相关文章

关于python的单实例模式

单实例模式一直是常用的设计模式,对于python的单实例模式,其实其本身就有实现 http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python/31887#31887 里面说到module,module只会初始化一次,天然的singleton.这是最为python的解决方案.将你所需要的属性和方法,直接暴露在模块中变成模块的全局变量和方法即可. 另外,如果

设计模式(三)单实例模式

引言 对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务:一个系统只能有一个窗口管理器或文件系统:一个系统只能有一个计时工具或ID(序号)生成器.如在Windows中就只能打开一个任务管理器.如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源:如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态.因此有时确保

单实例模式和互斥访问

场景说明:在实际的应用开发中,很多人没有注意到一点:在生成单实例的过程中,如果由线程去创建对象的实例,有可能在第一次检测到对象不存在的情况下,准备创建对象,此时由于多线程的缘故,恰巧当前线程被挂起,另一个线程同样执行到这个语句,于是创建一个对象,另一个线程冲睡眠中被唤醒,于是执行了创建对象,现在就有两个对象,完全背离了单实例的设计模式, 解决方法: 1)在主线程还没有创建多线程的时候,创建单实例,但是这里有一个问题:就不会达到延时加载的效果,变成了急剧加载,也就是说预先加载了对象,可能这个对象根

单实例模式

  前言:   单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中(jvm)一个类只有一个实例.即一个类只有一个对象实例:这几种模式有几种好处: 1.可以避免实例存在多个引起程序的逻辑错误(比如一个国家有多个主席,肯定会一团糟) 2.某些创建频繁的类,使用单列模式可以减轻内存的压力 3.因为类控制了实例化过程,所以类可以灵活更改实例化过程.   单列模式的三种模式: 1.饿汉模式 //饿汉式--典型的穷屌丝,吃了上顿没下顿.所以要提前准备(

线程安全的单实例模式

我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的动作由一个public的类方法代劳,该方法也返回单例类唯一的实例.单例大约有两种实现方法:懒汉与饿汉.懒汉:故名思义,不到万不得已就不会去实例化类,也就是说在第一次用到类实例的时候才会去实例化,节省内存.饿汉:饿了肯定要饥不择食.所以在单例类定义的时候就进行实例化.浪费内存特点与选择:由于要进行线程同步,所以在访问量比

3.1.17 自定义元类控制类的实例化的应用--单实例模式

#单例模式#实现方式一:# class MySQL:# __instance=None #__instance=obj1## def __init__(self):# self.host='127.0.0.1'# self.port=3306## @classmethod# def singleton(cls):# if not cls.__instance:# obj=cls()# cls.__instance=obj# return cls.__instance### def conn(se

python单实例

什么是python的单实例? 在python中如果没有特意指定我们所创建类的基类时,那么所有的类都继承于type这个类的祖宗,所有我们创建的类都是type这个鼻祖的实例. 例如: class A: def __init__(self): self.welcom = "hello world!" def __str__(self): return repr(self.welcom) a = A() print(a) 这是一个简单的类,在定义的时候没有显示的指定A这个类的基类,所以A这个类

C#设计模式-单实例

单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点. 1.经典的模式 namespace singleClass { class OnlyOneClass { private OnlyOneClass() { } private static OnlyOneClass instance; public static OnlyOneClass getInstance() { if (instance == null) { in

MySQL MGR集群单主模式的自动搭建和自动化故障修复

/*the waiting game:尽管人生如此艰难,不要放弃:不要妥协:不要失去希望*/ 随着MySQL MGR的版本的升级以及技术成熟,在把MHA拉下神坛之后, MGR越来越成为MySQL高可用的首选方案.MGR的搭建并不算很复杂,但是有一系列手工操作步骤,为了简便MGR的搭建和故障诊断,这里完成了一个自动化的脚本,来实现MGR的自动化搭建,自动化故障诊断以及修复. MGR自动化搭建为了简便起见,这里以单机多实例的模式进行测试,先装好三个MySQL实例,端口号分别是7001,7002,70