metaclass的学习理解

metaclass的学习理解


一句话概括,metaclass拦截了一般实例的创建流程,自己生成实例返回。
一般实例的创建流程

假设有个类A。

class A():
	def __init_(self, name)
		self.name = name
		print('__init__() in  A')
  1. 调用A.new(),创建实例实体。如果,A没有定义__new__(),会向父祖先类寻找;如果都没找到,会最后调用type.new()。
  2. 调用A.init(),初始化实例。
定义了metaclass后的流程

先定义一个metaclass类M。

class M(type):
	def __new__(cls, *args, **kwargs):
		print('this is metaclass>__new__()')
		obj = type.__new__(cls, *args, **kwargs)  #生成类
		return obj
	
	def __call__(cls, *args, **kwargs):
		obj = cls.__new__(cls, *args, **kwargs)  #生成类实例, 这里的cls是A
		print('in M.__call__()')
		#obj.__init__(*args, **kwargs) 
		return obj  

定义类A,指定metaclass是M。

class A(metaclass = M):
	def __init__(self, name):
		self.name = name
		print('__init__() in  A')

输出:

this is metaclass>__new__()

可以看出,是调用了M.new()生成类A。

生成实例
a = A('ant')

输出:

in M.__call__()

可以看到,实例生成a中并没有调用A.init,而是调用了M.call。这就是在类A定义时,定义了metaclass=M的结果。

官方文档

Customizing class creation python2
Customizing class creation python3.6

  1. metaclass可以类,也可以时函数,返回必须是一个类。

This variable can be any callable accepting arguments for name, bases, and dict. Upon class creation, the callable is used instead of the built-in type().

  1. metaclass的查找顺序。

The appropriate metaclass is determined by the following precedence rules:
* If dict[‘metaclass’] exists, it is used.
* Otherwise, if there is at least one base class, its metaclass is used (this looks for a class attribute first and if not found, uses its type).
* Otherwise, if a global variable named metaclass exists, it is used.
* Otherwise, the old-style, classic metaclass (types.ClassType) is used.


官方文档总是很有帮助!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值