前言
类在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'>]