黑马程序员技术交流社区
标题:
元类实现单例模式
[打印本页]
作者:
马总,我充钱
时间:
2018-6-11 21:43
标题:
元类实现单例模式
Python中的类也是对象。元类就是用来创建这些类(对象)的,元类就是类的类,你可以这样理解为:
MyClass = MetaClass() #元类创建
MyObject = MyClass() #类创建实例
实际上MyClass就是通过type()来创创建出MyClass类,它是type()类的一个实例;同时MyClass本身也是类,也可以创
建出自己的实例,这里就是MyObject
函数type实际上是一个元类。type就是Python在背后用来创建所有类的元类。现在你想知道那为什么type会全部采用小写形式而不是Type呢?好吧,我猜这是为了和str保持一致性,str是用来创建字符串对象的类,而int是用来创建整数对象的类。type就是创建类对象的类。你可以通过检查__class__属性来看到这一点。Python中所有的东西,注意,我是指所有的东西——都是对象。这包括整数、字符串、函数以及类。它们全部都是对象,而且它们都是从一个类创建而来。
那什么是单例呢?为什么我们要用单例设计模式?
我们首先来看看单例模式的使用场景,然后再来分析为什么需要单例模式。
• Python的logger就是一个单例模式,用以日志记录
• Windows的资源管理器是一个单例模式
• 线程池,数据库连接池等资源池一般也用单例模式
• 网站计数器
从这些使用场景我们可以总结下什么情况下需要单例模式:
1. 当每个实例都会占用资源,而且实例初始化会影响性能,这个时候就可以考虑使用单例模式,它给我们带来的好处是只有一个实例占用资源,并且只需初始化一次;
2. 当有同步需要的时候,可以通过一个实例来进行同步控制,比如对某个共享文件(如日志文件)的控制,对计数器的同步控制等,这种情况下由于只有一个实例,所以不用担心同步问题。
在python中实现单例模式有几种方法:
1. 使用模块
2. 使用装饰器
3. 使用类
4. 基于__new__方法实现(推荐使用,方便)
5. 基于metaclass元类方式实现
这里说说基于元类来实现。代码如下:
class Singleton(type):
def __init__(cls, name, bases, dic):
print('元类的__init__方法在被执行')
super(Singleton, cls).__init__(name, bases, dic)
cls.instance = None
def __call__(cls, *args, **kwargs):
if not cls.instance:
print('创建一个新对象')
cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
else:
print('单例,只能创建一个对象')
return cls.instance
class A(metaclass=Singleton):
# __metaclass__ = Singleton
pass # python3 取消了__metaclass__属性
a = A()
b = A()
print(a is b)
print(A.__dict__)
元类的__init__方法在被执行
创建一个新对象
单例,只能创建一个对象
True
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None, 'instance': <__main__.A object at 0x1027c5cf8>}
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2