Python单例类、元类详解

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

一.元类的定义

1.什么是元类

  • 元类是类的类,用来加工类,创建类
  • 实例是类创建的,而类是元类创建的
  • 类里面的mateclass为默认值,表明类是type创建的
class Person:
    pass

print(type(Person))  # 输出: <class 'type'>

这里我们会发现Person的类型是type

2.type的用法

type本身也是一个函数,用来创建动态类,他的语法是

type(类名, 父类元组, 属性字典)

我们来动态创建一个类

#第一个参数是类名
# #第二个是父类列表
# #第三个参数是类里面的属性
def __init__(name):
    return name
Myclass = type('Person',(object,),{'__doc__':'通过手动创建',
                                   'info':'两讲授','__init__':__init__})

三、元类工作流程

接下来的一段代码,会告诉你元类是如何创建类的

class MyType(type):#这里不写也默认有一个type,因为所有类都是type类型
    def __new__(cls, name,bases,dic):
        instance = super().__new__(cls,name,bases,dic)
        print(id(instance))# 1886804883152
        return instance
class People(metaclass=MyType):#表明这个是由Mytype类创建
    pass

print(id(People))# 1886804883152

具体流程:

  1. 定义了一个类并且指向了metaclass = Mytype,则MyType会自动帮你创建这个类
  2. MyType调用父类的__new__创建对象
  3. 调用父类的__init__初始化对象
  4. 返回类对象

四、使用元类加工一个类

# 加工类
class A:
    pass
class MyType(type):
    def __new__(cls, name,bases,dic):
        # print(name,bases,dic)
        #更改类名
        name = 'My' + name
        #添加父类
        bases = list(bases)
        bases.append(A)
        bases = tuple(bases)
        #将类方法中的大写改为小写
        temp = {}
        for k ,v in dic.items():
            if not k.startswith("__"):
                temp[k.lower()] = v
            else:
                temp[k] = v


        instance = super().__new__(cls,name,bases,temp)
        print(name,bases,temp)
        return instance

class People(metaclass=MyType):
    """注释"""
    INFO = "梁教授"
print(id(People),People.__name__)
p = People()
# print(p,id(p))

 通过对类的加工,我们给People类增加了父类A,我们将People中属性INFO改为了合法的info,同时我们将People的名字改为了MyPeople

五、单例类

Python编程中,单例模式是一种常见的设计模式,是为了防止一个实例被多次创建,只允许实例化一次,应用场景有数据库连接池,日志记录器,管理类等

1.单例类实现方式

1.1.使用__new__方法创建

__new__是用来创建实例的特殊方法,在init之前被调用

class Singleton:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls,'instance'):
            instance = super().__new__(cls)
            print(id(instance))
            setattr(cls,'instance',instance)
        return getattr(cls,'instance')
s = Singleton()
s1 = Singleton()
print(s is s1)
# 输出
# 2544341119536
# True

     1.2.使用元类创建单例

    class Singleton(type):
        instance = {}
        def __call__(cls, *args, **kwargs):
            #当类被调用时,就会触发__call__方法
    
            if cls not in cls.instance:
                cls.instance[cls] = super().__call__(*args,*kwargs)
            return cls.instance[cls]
    class SingletonManage(metaclass=Singleton):
        pass
    s = SingletonManage()
    s1 = SingletonManage()
    print(s is s1)#True

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值