【python】type和元类

前言

类在Python中是对象
python中用type或者元类定义类对象
类的__new__ 方法用于控制创建对象,创建并返回一个新的对象
类的__init__ 方法用于初始化对象
type(类名,基类元组(可以为空), 属性字典)
type(what=className, bases=(object,), dict=attrs)

元类

用于创建类的方法或者类称为元类,Python类的默认元类为type
demoClass.__class__ 即可得到demoClass这个类的元类
元类的作用在于自动拦截类的创建,修改类,并返回修改后的类

自定义元类

class MyMetaClass(type):
	def __new__(cls, name, bases, attrs):
		# 这里实现类属性的改写,然后返回一个新的类
		return type.__new__(cls, name, bases, attrs)

python2中使用元类

class DemoClass(object):
	# name = DemoClass
	# bases = object
	# attrs = DemoClass类中定义的变量,方法等。
	
	__metaclass__=MyMetaClass
	xxxx

python3中使用元类

class DemoClass(object, metaclass=MyMetaClass):
	xxxx

__metaclass__=MyMetaClass在类外面使用将作用于该py模块的所有类

元类与继承的区别

类并不能使用元类的属性,但派生类可以使用基类(继承类)的属性。
普通类的属性查找顺序为,类>object,
派生方式的类的属性查找顺序为,派生类>基类>基类的基类>object,
元类生成的类的属性查找顺序为,类>object,

元类冲突

多重继承过程中由于派生类的元类不是基类的元类的子类,就会造成元类冲突而报错。

	class Meta1(type):
	    def __new__(cls, *args, **kwargs):
	        return type.__new__(cls, *args, **kwargs)
	
	
	class Meta2(type):
	    def __new__(cls, *args, **kwargs):
	        return type.__new__(cls, *args, **kwargs)
	
	class B(metaclass=Meta1):
	    print('B')
	
	class A(metaclass=Meta2):
	    print('A')
	
	class C(A,B):
	    print('C')
	Traceback (most recent call last):
	  File "E:/GitHub/py3/PerformanceAnalysisReport/graph/demo.py", line 18, in <module>
	    class C(A,B):
	TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

解决方法可以定义一个继承基类的元类的类作为派生类的元类。

	class Meta1(type):
	    def __new__(cls, *args, **kwargs):
	        print('meta1')
	        return super().__new__(cls, *args, **kwargs)
	
	
	class Meta2(type):
	    def __new__(cls, *args, **kwargs):
	        print('meta2')
	        return super().__new__(cls, *args, **kwargs)
	
	class Meta(Meta1, Meta2):
	    print('meta')
	    pass
	
	class A(metaclass=Meta1):
	    print('A')
	
	class B(metaclass=Meta2):
	    print('B')
	
	class C(A, B, metaclass=Meta):
	    print('C')
	
	print(type(C))
	print(C.mro())
	# 创建类Meta时输出
	meta
	
	# 创建类A时输出
	A
	meta1
	# 创建类B时输出
	B
	meta2
	# 创建类C时输出
	C
	meta1
	meta2
	<class '__main__.Meta'>
	[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值