当前位置:首页 > Python技术文章 > python单例的两种实现方法介绍(附代码)

小结python单例的两种实现方法

  • 发布时间:
  • 作者:码农之家原创
  • 点击:97

这篇文章主要知识点是关于python单例、的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

ArcGIS下的Python编程
  • 类型:编程设计大小:144 MB格式:PDF作者:包瑞清
立即下载

python单例的两种实现方法介绍(附代码)

本篇文章给大家带来的内容是关于python单例的两种实现方法介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

 

这两天在看自己之前写的代码,所以正好把用过的东西整理一下,单例模式,在日常的代码工作中也是经常被用到,

所以这里把之前用过的不同方式实现的单例方式整理一下

装饰器的方式

这种方式也是工作中经常用的一种,用起来也比较方便,代码实现如下

 

def Singleton(cls):
    _instance = {}
    def _singleton(*args, **kwargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kwargs)
        return _instance[cls]

    return _singleton

 

如果我们工作的一个类需要用单例就通过类似下面的方式实现即可:

 

@Singleton
class A(object):    
def __init__(self, x):
     self.x = x

 

我个人还是挺喜欢这种方式的

类的方式实现

这里其实有一些问题就需要注意了,先看一下可能出现的错误代码

 

class Member(object):
    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Member, "_instance"):
            Member._instance = Member(*args, **kwargs)
        return Member._instance

 

乍一看这个类好像已经实现了单例,但是这里有一个潜在的问题,就是如果是多线程的情况,这样写就会有问题了,尤其是在当前类的初始化对象里有一些耗时操作时候

例如下面代码:

 

#! /usr/bin/env python3
# .-*- coding:utf-8 .-*-
import time
import threading
import random
class Member(object):
    def __init__(self):
        time.sleep(random.randint(1,3))
    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Member, "_instance"):
            Member._instance = Member(*args, **kwargs)
        return Member._instance
def task(arg):
    obj = Member.instance()
    print(obj)
for i in range(5):
    t = threading.Thread(target=task, args=[i,])
    t.start()

 

这段代码的执行结果会出现实例化了多个对象,导致你写的单例就没起到作用

当然自然而然我们会想起加锁,通过锁来控制,所以我们将上面代码进行更改:

 

#! /usr/bin/env python3
# .-*- coding:utf-8 .-*-
import time
import threading
import random
class Member(object):
    _instance_lock = threading.Lock()
    def __init__(self):
        i = random.randint(1, 3)
        print(i)
        time.sleep(i)
    @classmethod
    def instance(cls, *args, **kwargs):
        with Member._instance_lock:
            if not hasattr(Member, "_instance"):
                Member._instance = Member(*args, **kwargs)
        return Member._instance
def task():
    obj = Member.instance()
    print(obj)

for i in range(5):
    threading.Thread(target=task,).start()

 

但是上面的代码还有一个问题,就是当我们已经实例化过之后每次调用instance都会去请求锁,所以这点并不好,所以我们将这部分代码再次更改:

 

@classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Member, "_instance"):
            with Member._instance_lock:
                if not hasattr(Member, "_instance"):
                    Member._instance = Member(*args, **kwargs)
        return Member._instance

这样就很好的实现一个可以多线程使用的单例

以上就是本篇文章的全部内容,关于python更多精彩内容大家可以关注码农之家的Python视频教程和python文章教程栏目!!!

以上就是python单例的两种实现方法介绍(附代码)的详细内容,更多请关注码农之家其它相关文章!

以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。

推荐内容

idea2020注册激活码(激活到2100年)

实例分析Java实现的zip压缩及解压缩工具类

python3 pandas 如何读取MySQL数据和插入

ThinkPHP3.2.3框架如何实现分页功能

深入理解JS函数stack size计算方法

展开 +

收起 -

Python 相关电子书
学习笔记
网友NO.672006

python单例模式实例解析

本文实例为大家分享了python单例模式的具体代码,供大家参考,具体内容如下 多次实例化的结果指向同一个实例 单例模式实现方式 方式一: import settingsclass MySQL: __instance = None def __init__(self, ip, port): self.ip = ip self.port = port @classmethod def from_conf(cls): if cls.__instance is None: cls.__instance = cls(settings.IP,settings.PORT) return cls.__instanceobj1 = MySQL.from_conf()obj2 = MySQL.from_conf()obj3 = MySQL.from_conf()print(obj1)print(obj2)print(obj3) 方式二: import settingsdef singleton(cls): _instance = cls(settings.IP, settings.PORT) def wrapper(*args, **kwargs): if args or kwargs: obj = cls(*args, **kwargs) return obj return _instance return wrapper@singletonclass MySQL: def __init__(self, ip, port): self.ip = ip self.port = portobj1 = MySQL()obj2 = MySQL()obj3 = MySQL()print(obj1)print(obj2)print(obj3) 方式三: import settingsclass Mymeta(type): def __init__(self, class_name, class_bases, class_dic): self._……

网友NO.538640

python单例模式获取IP代理的方法详解

引言 最近在学习python,先说一下我学Python得原因,一个是因为它足够好用,完成同样的功能,代码量会比其他语言少很多,有大量的丰富的库可以使用,基本上前期根本不需要自己造什么轮子。第二个是因为目前他很火,网上各种资料都比较丰富,且质量尚可。接下来不如正题 在学习Python爬虫的时候,经常会遇见所要爬取的网站采取了反爬取技术导致爬取失败。高强度、高效率地爬取网页信息常常会给网站服务器带来巨大压力,所以同一个IP反复爬取同一个网页,就很可能被封,这里讲述一个爬虫技巧,设置代理IP 为什么需要代理 提到python,虽然他能干的事情很多,但是我们首先想起的一般都是爬虫。爬虫的作用是通过抓取网页,分析并获得网页中的内容。像php这类语言也是可以用curl来达到爬虫的效果,不过论爬虫库的数量和易用性就没办法和p……

网友NO.252960

python单例模式的多种实现方法

前言 单例模式(Singleton Pattern),是一种软件设计模式,是类只能实例化一个对象, 目的是便于外界的访问,节约系统资源,如果希望系统中 只有一个对象可以访问,就用单例模式, 显然单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。 在 Python 中,我们可以用多种方法来实现单例模式: 使用模块 使用 __new__ 使用装饰器(decorator) 使用元类(metaclass) 概念 简单说,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个(当然也可以不存在) 例子: 一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个,这里就可以通过单例模式来避免两个打印作业同时输出到打印机中,即在整个的打……

网友NO.637446

python单例模式是什么

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。 比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。 单例模式的要点有三个: 一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。 在 Python 中,我们……

<
1
>

电子书 编程教程 文档 软件 源码 视频

Copyright 2018-2020 xz577.com 码农之家

本站所有电子书资源不再提供下载地址,只分享来路

免责声明:网站所有作品均由会员网上搜集共同更新,仅供读者预览及学习交流使用,下载后请24小时内删除

版权投诉 / 书籍推广 / 赞助:QQ:520161757