全国咨询/投诉热线:400-618-9090

首页技术文章正文

元类实现单例模式

更新时间:2018-07-13 来源:黑马程序员JavaEE培训学院 浏览量:

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的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>}

本文版权归黑马程序员JavaEE学院所有,欢迎转载,转载请注明作者出处。谢谢!

作者:黑马程序员JavaEE培训学院

首发:http://java.itheima.com/

javaee

python

web

ui

cloud

test

c

netmarket

pm

Linux

movies

robot

http://www.itcast.cn/subject/uizly/index.shtml?seozxuids

14天免费试学

基础班入门课程限时免费

申请试学名额

15天免费试学

基础班入门课程限时免费

申请试学名额

15天免费试学

基础班入门课程限时免费

申请试学名额

15天免费试学

基础班入门课程限时免费

申请试学名额

20天免费试学

基础班入门课程限时免费

申请试学名额

8天免费试学

基础班入门课程限时免费

申请试学名额

20天免费试学

基础班入门课程限时免费

申请试学名额

5天免费试学

基础班入门课程限时免费

申请试学名额

0天免费试学

基础班入门课程限时免费

申请试学名额

12天免费试学

基础班入门课程限时免费

申请试学名额

5天免费试学

基础班入门课程限时免费

申请试学名额

5天免费试学

基础班入门课程限时免费

申请试学名额

10天免费试学

基础班入门课程限时免费

申请试学名额
在线咨询 我要报名