Mixins机制
Mixins机制:子类混合不同类的功能,本质仍是多继承,不依赖于子类的实现。
使用:
1. 主类:就是大部分都是主要的功能
2. 辅类:就是一些辅助的功能
3. 辅类的类名也有讲究:一般以mixin、able、ible等结尾
4. 继承的位置也有讲究
eg:
class Vehicle: # 交通工具 pass class FlyMinix(): def fly(self): '''飞行功能相应的代码''' print("I am flying") class CivilAircraft(FlyMinix, Vehicle): # 民航飞机 pass class Helicopter(FlyMinix, Vehicle): # 直升飞机 pass class Car(Vehicle): # 汽车并不会飞,但按照上述继承关系,汽车也能飞了 pass import socketserver
元类
元类:即产生类的类
‘type其实查看的是对象是由哪个类的产生的’
class MyClass(object): pass obj = MyClass() # <class '__main__.MyClass'> # print(type(obj)) # 可以查看出obj对象是有哪个类产生的 """你说我打印type(MyClass) 它的结果应该是什么呢?""" class type(object): print(type(MyClass)) # <class 'type'> 我就可以认为MyClass类就是有type类产生的
我们之前用class造出来的类都是type类造出来的。默认情况下,所有的类的元类就是type
class Student(): pass print(type(Student)) # <class 'type'> class C1(): pass print(type(C1)) # <class 'type'>
产生类的两种方式
1. class 类名():
pass
2. 由于所有的类都是type类造出来的,所以我们也可以使用type类造出来一个新类,
type(object_or_name,basea,dict) # 以上三个条件就是造出一个新类 type("类名","父类",“类的名称空间”)
为什么要学习元类?
元类是造出类的类,所以可以对类进行高度的定制化。
定制化代码:如果想要该类的行为,应该在元类的__init__方法中做修改。
想要改变父类的__init__方法,但是不能直接修改源代码。可以写一个新的子类来继承父类type,然后再子类中写代码,在重新执行一些父类的__init__方法。
对象是如何产生的:执行了产生这个对象的类内部的__init__方法
"""元类不能直接继承""" class MyTypeClass(type): def __init__(self, cls_name, cls_bases=None, cls_dict=None): print(cls_name, cls_bases, cls_dict) # C1 () {'__module__': '__main__', '__qualname__': 'C1'} # cls_name:它就是类名 # 限制类名必须是首字母大写 if not cls_name.istitle(): raise Exception("类名必须是首字母大写") super().__init__(cls_name, cls_bases=None, cls_dict=None) class C1(metaclass=MyTypeClass): school = 'Sh' class a(metaclass=MyTypeClass): pass
元类的进阶操作
类名(),会执行产生类的类中的__call__方法。而这个类恰好是元类type。
class MyClass(type): def __call__(self, *args, **kwargs): print("__call__ 执行了") print(args, kwargs) """限制传参的方式必须是关键字传参,只需要args是空就行""" if args: raise Exception("传参必须是关键字传参") super(MyClass, self).__call__(*args, **kwargs) class C1(metaclass=MyClass): def __init__(self, name): print("__init__ 执行了") # self.name = name """看C1类里面的__init__方法和元类里面的__call__方法的执行顺序""" # 得出结论,其实在执行类的__init__之前,先执行了__call__方法 obj = C1(name='kevin') # 都是位置传参,强制要求必须是关键字传参
标签:__,进阶,Mixins,元类,init,type,class,cls From: https://www.cnblogs.com/Lucky-Hua/p/17521085.html