有什么做服装的网站,宁波网络营销咨询,百度指数数据分析报告,linux上安装wordpress点评#xff1a;单例模式是指让一个类只能创建出唯一的实例#xff0c;这个题目在面试中出现的频率极高#xff0c;因为它考察的不仅仅是单例模式#xff0c;更是对Python语言到底掌握到何种程度#xff0c;建议大家用装饰器和元类这两种方式来实现单例模式#xff0c;因…点评单例模式是指让一个类只能创建出唯一的实例这个题目在面试中出现的频率极高因为它考察的不仅仅是单例模式更是对Python语言到底掌握到何种程度建议大家用装饰器和元类这两种方式来实现单例模式因为这两种方式的通用性最强而且也可以顺便展示自己对装饰器和元类中两个关键知识点的理解。
方法一 使用装饰器实现单例模式。
from functools import wraps
def 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.__instance class President(metaclassSingletonMeta): pass 扩展Python是面向对象的编程语言在面向对象的世界中一切皆为对象。对象是通过类来创建的而类本身也是对象类这样的对象是通过元类来创建的。我们在定义类时如果没有给一个类指定父类那么默认的父类是object如果没有给一个类指定元类那么默认的元类是type。通过自定义的元类我们可以改变一个类默认的行为就如同上面的代码中我们通过元类的__call__魔术方法改变了President类的构造器那样。 补充关于单例模式在面试中还有可能被问到它的应用场景。通常一个对象的状态是被其他对象共享的就可以将其设计为单例例如项目中使用的数据库连接池对象和配置对象通常都是单例这样才能保证所有地方获取到的数据库连接和配置信息是完全一致的而且由于对象只有唯一的实例因此从根本上避免了重复创建对象造成的时间和空间上的开销也避免了对资源的多重占用。
再举个例子项目中的日志操作通常也会使用单例模式这是因为共享的日志文件一直处于打开状态只能有一个实例去操作它否则在写入日志的时候会产生混乱。 这个我还没完全弄懂我懂了之后再来补充内容解释