Python设计模式中单例模式的实现及在Tornado中的应用
单例模式的实现方式
将类实例绑定到类变量上
class Singleton(object): _instance = None def __new__(cls, *args): if not isinstance(cls._instance, cls): cls._instance = super(Singleton, cls).__new__(cls, *args) return cls._instance
但是子类在继承后可以重写__new__以失去单例特性
class D(Singleton): def __new__(cls, *args): return super(D, cls).__new__(cls, *args)
使用装饰器实现
def singleton(_cls): inst = {} def getinstance(*args, **kwargs): if _cls not in inst: inst[_cls] = _cls(*args, **kwargs) return inst[_cls] return getinstance @singleton class MyClass(object): pass
问题是这样装饰以后返回的不是类而是函数,当然你可以singleton里定义一个类来解决问题,但这样就显得很麻烦了
使用__metaclass__,这个方式最推荐
class Singleton(type): _inst = {} def __call__(cls, *args, **kwargs): if cls not in cls._inst: cls._inst[cls] = super(Singleton, cls).__call__(*args) return cls._inst[cls] class MyClass(object): __metaclass__ = Singleton
Tornado中的单例模式运用
来看看tornado.IOLoop中的单例模式:
class IOLoop(object): @staticmethod def instance(): """Returns a global `IOLoop` instance. Most applications have a single, global `IOLoop` running on the main thread. Use this method to get this instance from another thread. To get the current thread's `IOLoop`, use `current()`. """ if not hasattr(IOLoop, "_instance"): with IOLoop._instance_lock: if not hasattr(IOLoop, "_instance"): # New instance after double check IOLoop._instance = IOLoop() return IOLoop._instance
为什么这里要double check?来看个这里面简单的单例模式,先来看看代码:
class Singleton(object): @staticmathod def instance(): if not hasattr(Singleton, '_instance'): Singleton._instance = Singleton() return Singleton._instance
在 Python 里,可以在真正的构造函数__new__里做文章:
class Singleton(object): def __new__(cls, *args, **kwargs): if not hasattr(cls, '_instance'): cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._instance
这种情况看似还不错,但是不能保证在多线程的环境下仍然好用,看图:
出现了多线程之后,这明显就是行不通的。
1.上锁使线程同步
上锁后的代码:
import threading class Singleton(object): _instance_lock = threading.Lock() @staticmethod def instance(): with Singleton._instance_lock: if not hasattr(Singleton, '_instance'): Singleton._instance = Singleton() return Singleton._instance
这里确实是解决了多线程的情况,但是我们只有实例化的时候需要上锁,其它时候Singleton._instance已经存在了,不需要锁了,但是这时候其它要获得Singleton实例的线程还是必须等待,锁的存在明显降低了效率,有性能损耗。
2.全局变量
在 Java/C++ 这些语言里还可以利用全局变量的方式解决上面那种加锁(同步)带来的问题:
class Singleton { private static Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return instance; } }
在 Python 里就是这样了:
class Singleton(object): @staticmethod def instance(): return _g_singleton _g_singleton = Singleton() # def get_instance(): # return _g_singleton
但是如果这个类所占的资源较多的话,还没有用这个实例就已经存在了,是非常不划算的,Python 代码也略显丑陋……
所以出现了像tornado.IOLoop.instance()那样的double check的单例模式了。在多线程的情况下,既没有同步(加锁)带来的性能下降,也没有全局变量直接实例化带来的资源浪费。
3.装饰器
如果使用装饰器,那么将会是这样:
import functools def singleton(cls): ''' Use class as singleton. ''' cls.__new_original__ = cls.__new__ @functools.wraps(cls.__new__) def singleton_new(cls, *args, **kw): it = cls.__dict__.get('__it__') if it is not None: return it cls.__it__ = it = cls.__new_original__(cls, *args, **kw) it.__init_original__(*args, **kw) return it cls.__new__ = singleton_new cls.__init_original__ = cls.__init__ cls.__init__ = object.__init__ return cls # # Sample use: # @singleton class Foo: def __new__(cls): cls.x = 10 return object.__new__(cls) def __init__(self): assert self.x == 10 self.x = 15 assert Foo().x == 15 Foo().x = 20 assert Foo().x == 20
def singleton(cls): instance = cls() instance.__call__ = lambda: instance return instance # # Sample use # @singleton class Highlander: x = 100 # Of course you can have any attributes or methods you like. Highlander() is Highlander() is Highlander #=> True id(Highlander()) == id(Highlander) #=> True Highlander().x == Highlander.x == 100 #=> True Highlander.x = 50 Highlander().x == Highlander.x == 50 #=> True

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

手机XML转PDF的速度取决于以下因素:XML结构的复杂性手机硬件配置转换方法(库、算法)代码质量优化手段(选择高效库、优化算法、缓存数据、利用多线程)总体而言,没有绝对的答案,需要根据具体情况进行优化。

不可能直接在手机上用单一应用完成 XML 到 PDF 的转换。需要使用云端服务,通过两步走的方式实现:1. 在云端转换 XML 为 PDF,2. 在手机端访问或下载转换后的 PDF 文件。

C语言中没有内置求和函数,需自行编写。可通过遍历数组并累加元素实现求和:循环版本:使用for循环和数组长度计算求和。指针版本:使用指针指向数组元素,通过自增指针遍历高效求和。动态分配数组版本:动态分配数组并自行管理内存,确保释放已分配内存以防止内存泄漏。

没有APP可以将所有XML文件转成PDF,因为XML结构灵活多样。XML转PDF的核心是将数据结构转换为页面布局,需要解析XML并生成PDF。常用的方法包括使用Python库(如ElementTree)解析XML,并利用ReportLab库生成PDF。对于复杂XML,可能需要使用XSLT转换结构。性能优化时,考虑使用多线程或多进程,并选择合适的库。

XML格式化工具可以将代码按照规则排版,提高可读性和理解性。选择工具时,要注意自定义能力、对特殊情况的处理、性能和易用性。常用的工具类型包括在线工具、IDE插件和命令行工具。

直接在手机上将XML转换为PDF并不容易,但可以借助云端服务实现。推荐使用轻量级手机App上传XML文件并接收生成的PDF,配合云端API进行转换。云端API使用无服务器计算服务,选择合适的平台至关重要。处理XML解析和PDF生成时需要考虑复杂性、错误处理、安全性和优化策略。整个过程需要前端App与后端API协同工作,需要对多种技术有所了解。

可以将 XML 转换为图像,方法是使用 XSLT 转换器或图像库。XSLT 转换器:使用 XSLT 处理器和样式表,将 XML 转换为图像。图像库:使用 PIL 或 ImageMagick 等库,从 XML 数据创建图像,例如绘制形状和文本。

用大多数文本编辑器即可打开XML文件;若需更直观的树状展示,可使用 XML 编辑器,如 Oxygen XML Editor 或 XMLSpy;在程序中处理 XML 数据则需使用编程语言(如 Python)与 XML 库(如 xml.etree.ElementTree)来解析。
