什么是元类
- 在python中可以看到很多的对象都是type类型,那么什么是type类型呢?即元类。元类就是创建所有类的一个模板,是创建python所有类的类,里面封装了一些方法。
使用type创建类
- type的第一个用法就是查看对象所属类
- 可以使用type创建类,type需要传入三个参数:name、bases、dict。需要注意传入时不用写形参。
- name 类名
- bases 继承的基类,元组形式传入
- dict 类封装的方法,以字典传入
- 如下所示:
```python
使用type创建类
def init(self): print(“我要初始化!”)
def func(self): print(“我是普通方法!”)
@classmethod def class_func(cls): print(“我是类方法!”)
@staticmethod def static_func(): print(“我是静态方法!”)
MyClassType = type(
“MyClassType”,
(object, ),
{“init“: init, “func”: func, “class_func”: class_func, “static_func”:static_func}
)
c = MyClassType() c.static_func() MyClassType.class_func()
![image.png](https://cdn.nlark.com/yuque/0/2020/png/1325594/1594455596422-597076e6-d4ea-44e3-a7ea-bafe7a544ac5.png#align=left&display=inline&height=79&margin=%5Bobject%20Object%5D&name=image.png&originHeight=87&originWidth=1218&size=35101&status=done&style=none&width=1100)
<a name="UMm49"></a>
### 为什么使用元类?
- 可以通过元类控制子类实现一些功能。
- 可以通过abc模块里的ABCMeta类来实现
<a name="NidMa"></a>
#### 抽象基类
- 在基类中实现一些方法,但是什么都不用做,但是强迫子类重写这些方法,不然不能实例化子类,从而达到了子类继承时符合要求。
```python
from abc import ABCMeta,abstractmethod
class MyAbstract(object, metaclass=ABCMeta):
# 定义抽象方法
@abstractmethod
def say_something(self):
pass
class MyClass(MyAbstract):
# 重写抽象方法
def say_something(self):
print("nihao !")
my_class = MyClass()
my_class.say_something()
print("my_class", type(my_class))
print("MyClass", type(MyClass))
print("MyAbstract", type(MyAbstract))
- 如果不重写say_something这个方法,就会报错,如下: ```python from abc import ABCMeta,abstractmethod
class MyAbstract(object, metaclass=ABCMeta): @abstractmethod def say_something(self): pass
class MyClass(MyAbstract):
# def say_something(self):
# print("nihao !")
pass
my_class = MyClass()
![image.png](https://cdn.nlark.com/yuque/0/2020/png/1325594/1594457185450-5eb582d0-b8d3-4487-8f40-126a10b03d46.png#align=left&display=inline&height=90&margin=%5Bobject%20Object%5D&name=image.png&originHeight=125&originWidth=1525&size=73415&status=done&style=none&width=1100)
<a name="Zozlq"></a>
#### 其他用法
- 强迫写说明文档
```python
from abc import ABCMeta,abstractmethod
class MyAbstract(object, metaclass=ABCMeta):
@abstractmethod
def say_something(self):
pass
def __new__(cls):
if cls.__dict__["__doc__"] is not None:
return super().__new__(cls)
else:
raise TypeError("没有说明文档,亲!")
class MyClass(MyAbstract):
"""doc"""
def say_something(self):
print("nihao !")
my_class = MyClass()
print(my_class.__doc__)
结果如下:
如果没有子类没有写说明文档运行如下:
继承顺序
- python 3之后的类继承顺序使用的c3算法,可以使用mro方法查看继承顺序
- 由下至上继承
- 从左至右继承 ```python from abc import ABCMeta
class A(object): pass
class B: pass
class C(A, B): pass
print(C.mro) ```