【Python】 类的原理 与 metaclass 单例模式

class 实际上是继承于type
而构建一个type,需要三个东西,

  1. 类的名字
  2. 它的父类,tuple类型元组
  3. dict

type() 输入一个参数,返回的是参数的type
type() 输入三个参数,返回的是一个新的type

class A():
	pass
A = type("A",(),{})

以上两种写法是完全等价的。

为什么要引入__metaclass__?

因为type()直接调用到C函数里,我们没办法自定义一些中间的过程了。
所以提供给我们一个__metaclass__的方法,去定义中间的过程。

我们想做这样一件事,

class M(type):
	def __new__(cls, name, bases, dict):
		return type.__new__(cls, name, bases, dict)
A = M("A",(),{})

让M返回我需要的类。

用metaclass的写法重写一下

class M(type):
	def __new__(cls, name, bases, dict):
		return type.__new__(cls, name, bases, dict)
class A(metaclass = M):
	pass

M的__new__函数是在定义class A的时候执行的

其实还可以往metaclass里放一个__init__函数、一个__call__函数

__init__和__new__的区别就是,init的时候已经有A这个Object了

class M(type):
    def __new__(cls, name, bases, dict):
        return type.__new__(cls, name, bases, dict)
    def __init__(self, name, bases, dict):
        return type.__init__(self, name, bases, dict)
    def __call__(cls,*args,**kwargs):
        return type.__call__(cls, *args, **kwargs)

如果用super().代替type.
在__init__和__call__里需要把self,cls去掉
__new__里面不用去掉

单例模式快速实现

class M(type):
    def __call__(cls,*args,**kwargs):
        if hasattr(cls,"_instance"):
            return cls._instance
        cls._instance = type.__call__(cls, *args, **kwargs)
        return cls._instance
class A:
    __metaclass__ = M
    pass

print id(A())
print id(A())
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值