iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >在Python中如何实现单例模式
  • 555
分享到

在Python中如何实现单例模式

2023-06-01 23:06:39 555人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

本篇内容主要讲解“在python中如何实现单例模式”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“在Python中如何实现单例模式”吧!方法一:使用装饰器实现单例模式。from functools

本篇内容主要讲解“在python中如何实现单例模式”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“在Python中如何实现单例模式”吧!

方法一:使用装饰器实现单例模式。

from functools import wrapsdef singleton(cls):
   """单例类装饰器"""
   instances = {}

   @wraps(cls)
   def wrapper(*args, **kwargs):
       if cls not in instances:
           instances[cls] = cls(*args, **kwargs)
       return instances[cls]

   return wrapper@singleton
class President:
   pass

扩展:装饰器是Python中非常有特色的语法,用一个函数去装饰另一个函数或类,为其添加额外的能力。通常通过装饰来实现的功能都属横切关注功能,也就是跟正常的业务逻辑没有必然联系,可以动态添加或移除的功能。装饰器可以为代码提供缓存、代理、上下文环境等服务,它是对设计模式中代理模式的践行。在写装饰器的时候,带装饰功能的函数(上面代码中的wrapper函数)通常都会用functools模块中的wraps再加以装饰,这个装饰器最重要的作用是给被装饰的类或函数动态添加一个__wrapped__属性,这个属性会将被装饰之前的类或函数保留下来,这样在我们不需要装饰功能的时候,可以通过它来取消装饰器,例如可以使用President = President.__wrapped__来取消对President类做的单例处理。需要提醒大家的是:上面的单例并不是线程安全的,如果要做到线程安全,需要对创建对象的代码进行加的处理。在Python中可以使用threading模块的RLock对象来提供锁,可以使用锁对象的acquire和release方法来实现加锁和解锁的操作。当然,更为简便的做法是使用锁对象的with上下文语法来进行隐式的加锁和解锁操作。

方法二:使用元类实现单例模式。

class SingletonMeta(type):
   """自定义单例元类"""

   def __init__(cls, *args, **kwargs):
       cls.__instance = None
       super().__init__(*args, **kwargs)

   def __call__(cls, *args, **kwargs):
       if cls.__instance is None:
           cls.__instance = super().__call__(*args, **kwargs)
       return cls.__instanceclass President(metaclass=SingletonMeta):
   pass

扩展:Python是面向对象编程语言,在面向对象的世界中,一切皆为对象。对象是通过类来创建的,而类本身也是对象,类这样的对象是通过元类来创建的。我们在定义类时,如果没有给一个类指定父类,那么默认的父类是object,如果没有给一个类指定元类,那么默认的元类是type。通过自定义的元类,我们可以改变一个类默认的行为,就如同上面的代码中,我们通过元类的__call__魔术方法,改变了President类的构造器那样。

关于单例模式,在面试中还有可能被问到它的应用场景。通常一个对象的状态是被其他对象共享的,就可以将其设计为单例,例如项目中使用的数据库连接池对象和配置对象通常都是单例,这样才能保证所有地方获取到的数据库连接和配置信息是完全一致的;而且由于对象只有唯一的实例,因此从根本上避免了重复创建对象造成的时间和空间上的开销,也避免了对资源的多重占用。再举个例子,项目中的日志操作通常也会使用单例模式,这是因为共享的日志文件一直处于打开状态,只能有一个实例去操作它,否则在写入日志的时候会产生混乱。

题目002:不使用中间变量,交换两个变量a和b的值。

点评:典型的送人头的题目,在其他编程语言中不使用中间变量交换两个变量的值可以使用异或运算,Python中还可以通过内置的字节码指令直接交换两个变量的值。

方法一:

a = a ^ b
b = a ^ b
a = a ^ b

方法二:

a, b = b, a

扩展:需要注意,a, b = b, a这种做法其实并不是元组解包,虽然很多人都这样认为。Python字节码指令中有ROT_TWO指令来支持这个操作,类似的还有ROT_THREE,对于3个以上的元素,如a, b, c, d = b, c, d, a,才会用到创建元组和元组解包。想知道你的代码对应的字节码指令,可以使用Python标准库中dis模块的dis函数来反汇编你的Python代码。

题目003:写一个删除列表中重复元素的函数,要求去重后元素相对位置保持不变。

点评:这个题目在初中级Python岗位面试的时候经常出现,题目源于《Python Cookbook》这本书第一章的第10个问题,有很多面试题其实都是这本书上的原题,所以建议大家有时间的话好好研读一下这本书。

def dedup(items):
   no_dup_items = []
   seen = set()
   for item in items:
       if item not in seen:
           no_dup_items.append(item)
           seen.add(item)
   return no_dup_items

当然,也可以像《Python Cookbook》书上的代码那样,把上面的函数改造成一个生成器。

def dedup(items):
   seen = set()
   for item in items:
       if item not in seen:
           yield item
           seen.add(item)

扩展:由于Python中的集合底层使用哈希存储,所以集合的in和not in成员运算在性能上远远优于列表,所以上面的代码我们使用了集合来保存已经出现过的元素。集合中的元素必须是hashable对象,因此上面的代码在列表元素不是hashable对象时会失效,要解决这个问题可以给函数增加一个参数,该参数可以设计为返回哈希码或hashable对象的函数。

题目004:假设你使用的是官方的CPython,说出下面代码的运行结果。

点评:下面的程序对实际开发并没有什么意义,但却是CPython中的一个大坑,这道题旨在考察面试者对官方的Python解释器到底了解到什么程度。

a, b, c, d = 1, 1, 1000, 1000
print(a is b, c is d)

def foo():
   e = 1000
   f = 1000
   print(e is f, e is d)
   g = 1
   print(g is a)

foo()

结果:

True False
True False
True

上面代码中a is b的结果是True但c is d的结果是False,这一点的确让人费解。这个结果是因为CPython出于性能优化的考虑,把频繁使用的整数对象用一个叫small_ints的对象池缓存起来造成的。small_ints缓存的整数值被设定为[-5, 256]这个区间,也就是说,如果使用CPython解释器,在任何引用这些整数的地方,都不需要重新创建int对象,而是直接引用缓存池中的对象。如果整数不在该范围内,那么即便两个整数的值相同,它们也是不同的对象。

CPython底层为了进一步提升性能还做了一个设定:对于同一个代码块中值不在small_ints缓存范围之内的整数,如果同一个代码块中已经存在一个值与其相同的整数对象,那么就直接引用该对象,否则创建新的int对象。需要大家注意的是,这条规则对数值型适用,但对字符串则需要考虑字符串的长度,这一点可以自行证明。

扩展:如果你用PyPy(另一种Python解释器实现,支持JIT,对CPython的缺点进行了改良,在性能上优于CPython,但对三方库的支持略差)来运行上面的代码,你会发现所有的输出都是True。

题目005:Lambda函数是什么,举例说明的它的应用场景。

点评:这个题目主要想考察的是Lambda函数的应用场景,潜台词是问你在项目中有没有使用过Lambda函数,具体在什么场景下会用到Lambda函数,借此来判断你写代码的能力。因为Lambda函数通常用在高阶函数中,主要的作用是通过传入或返回函数实现代码的解耦合。

Lambda函数也叫匿名函数,它功能简单用一行代码就能实现的小型函数。Python中的Lambda函数只能写一个表达式,这个表达式的执行结果就是函数的返回值,不用写return关键字。Lambda函数因为没有名字,所以也不会跟其他函数发生命名冲突的问题。

面试的时候有可能还会考你用Lambda函数来实现一些功能,也就是用一行代码来实现题目要求的功能,例如:用一行代码实现求阶乘的函数,用一行代码实现求最大公约数的函数等。

fac = lambda x: __import__('functools').reduce(int.__mul__, range(1, x + 1), 1)
GCd = lambda x, y: y % x and gcd(y % x, x) or x

Lambda函数其实最为主要的用途是把一个函数传入另一个高阶函数(如Python内置的filter、map等)中来为函数做解耦合,增强函数的灵活性和通用性。下面的例子通过使用filter和map函数,实现了从列表中筛选出奇数并求平方构成新列表的操作,因为用到了高阶函数,过滤和映射数据的规则都是函数的调用者通过另外一个函数传入的,因此这filter和map函数没有跟特定的过滤和映射数据的规则耦合在一起。

items = [12, 5, 7, 10, 8, 19]
items = list(map(lambda x: x ** 2, filter(lambda x: x % 2, items)))
print(items)    # [25, 49, 361]

当然,用列表的生成式来实现上面的代码更加简单明了,如下所示。

items = [12, 5, 7, 10, 8, 19]
items = [x ** 2 for x in items if x % 2]
print(items)    # [25, 49, 361]

到此,相信大家对“在Python中如何实现单例模式”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: 在Python中如何实现单例模式

本文链接: https://www.lsjlt.com/news/227970.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 在Python中如何实现单例模式
    本篇内容主要讲解“在Python中如何实现单例模式”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“在Python中如何实现单例模式”吧!方法一:使用装饰器实现单例模式。from functools...
    99+
    2023-06-01
  • Python实现单例模式
    1.什么是单例? 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,单例模式是一种对象创建型模式。那么单例模式有什么用途呢?举个常见的单例模式例子,我们平时使用的电脑上都有一个回收站,在整个操作系统中,回...
    99+
    2023-01-31
    模式 Python
  • 如何实现单例模式
    本篇文章给大家分享的是有关如何实现单例模式,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。header("Content-type:t...
    99+
    2024-04-02
  • java设计模式中如何实现单例模式
    这篇文章将为大家详细讲解有关java设计模式中如何实现单例模式,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。下面是一个简单的小实例://简单懒汉式 public class ...
    99+
    2023-05-30
    java
  • 如何使用Python中的@classmethod实现单例模式
    这篇文章主要介绍了如何使用Python中的@classmethod实现单例模式,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。@classmethod实现单例模式:class&...
    99+
    2023-06-17
  • Python中怎么实现单例模式
    本文小编为大家详细介绍“Python中怎么实现单例模式”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python中怎么实现单例模式”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。...
    99+
    2024-04-02
  • python单例模式之seleniumdriver实现单例
    目录一、使用装饰器实现单例二、web自动化driver实现单例模式2.1 编写单例模式的装饰器2.2 driver 使用装饰器,实现单例模式2.3 获取driver的实例,就是单例了...
    99+
    2024-04-02
  • JavaScript如何实现单例模式
    小编给大家分享一下JavaScript如何实现单例模式,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!单例模式通过 ES6 的 Proxy 拦截构造函数的执行方法来...
    99+
    2023-06-27
  • PHP单例模式如何实现
    这篇文章主要介绍“PHP单例模式如何实现”,在日常操作中,相信很多人在PHP单例模式如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PHP单例模式如何实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-07-04
  • Android如何实现单例模式
    这篇文章主要介绍了Android如何实现单例模式,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一.饿汉式public class SingletionSt...
    99+
    2023-06-15
  • java单例模式如何实现
    本篇内容主要讲解“java单例模式如何实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java单例模式如何实现”吧!0x01 宫女请安在朕的后宫中,皇后当之无愧的是天下第一(朕只能当...
    99+
    2023-06-19
  • 在java项目中如何实现一个单例模式
    在java项目中如何实现一个单例模式?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。java设计模式--单例模式 单例设计模式Singleton是一种创...
    99+
    2023-05-31
    java 单例模式 ava
  • 如何使用Python继承实现单例模式
    这篇文章给大家分享的是有关如何使用Python继承实现单例模式的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。继承实现:class ParentClass:    ...
    99+
    2023-06-17
  • 如何使用Python元类实现单例模式
    这篇文章主要介绍了如何使用Python元类实现单例模式,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。元类实现:class MetaClass(type): ...
    99+
    2023-06-17
  • Python中单例模式的实现方法
    单例 — 让 类 创建的对象,在系统中 只有唯一的一个实例; 1)、定义一个类属性,初始值是 None ,用于记录 单例对象的引用;2)、重写 new 方法;3)、如果 ...
    99+
    2024-04-02
  • java中枚举如何实现单例模式
    java中枚举实现单例模式的方法:可以使用单元素枚举类型实现,语法格式:“public enum Singleton {INSTANCE; private Singleton() {}}”,一般情况下枚举里面创建实例是线程安全的。用法说明:...
    99+
    2024-04-02
  • 在Python中实现单例模式的方法有哪些
    本篇内容主要讲解“在Python中实现单例模式的方法有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“在Python中实现单例模式的方法有哪些”吧!单例模式(Singleton Pattern...
    99+
    2023-06-16
  • Java的单例模式如何实现
    这篇文章主要介绍“Java的单例模式如何实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java的单例模式如何实现”文章能帮助大家解决问题。什么是单例模式单例模式(Singleton Patter...
    99+
    2023-06-27
  • 如何实现单例设计模式
    这篇文章主要讲解了“如何实现单例设计模式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现单例设计模式”吧! 单例模式单例模式(Singleton Pattern)是 Java...
    99+
    2023-06-15
  • spring的单例模式如何现实
    在Spring中,有多种方式来实现单例模式: 默认的单例模式:Spring容器默认情况下会将所有声明为Bean的对象作为单例对象...
    99+
    2024-02-29
    spring
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作