python装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式(一)
介绍装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式
有时候需要給类添加额外的东西,有些东西很频繁,每个类都需要,如果不想反复的复制粘贴到每个类,可以动态添加。
1 # coding=utf-8 2 3 def create_class_attribution(cls): 4 def _inner(*args, **kwargs): 5 if not hasattr(cls, 'xx'): 6 cls.xx = 1 7 8 def funa(self, a, b): 9 return a + b 10 11 if not hasattr(cls, 'funa'): 12 cls.funa = funa 13 return cls(*args, **kwargs) 14 15 return _inner 16 17 18 class Base(): 19 # __metaclass__ = Meta 20 def __new__(cls, *args, **kwargs): 21 if not hasattr(cls, 'yy'): 22 cls.yy = 2 23 return super().__new__(cls) 24 25 def funb(self, a, b): 26 return a + b 27 28 29 class MyType(type): 30 def __new__(cls, name, bases, attrs): 31 attrs['zz'] = 3 32 attrs['func'] = lambda self, a, b: a + b 33 return super(MyType, cls).__new__(cls, name, bases, attrs) 34 35 36 class MyMixin(): 37 def __init__(self, *args, **kwargs): 38 if not hasattr(self, 'ww'): 39 self.__class__.ww = 4 40 41 def fund(self, a, b): 42 return a + b 43 44 45 @create_class_attribution 46 class A(MyMixin, Base, metaclass=MyType): 47 pass 48 49 50 a = A() 51 print (a.xx) 52 print (a.yy) 53 print (a.zz) 54 print (a.ww) 55 print (a.funa(1, 2)) 56 print (a.funb(3, 4)) 57 print (a.func(5, 6)) 58 print (a.fund(7, 8))
这样就完成了给类添加属性和方法了。
A类什么都不写,a的实例就有4个自定义的方法和4个属性了。
1、其中,元类,是在代码不进行任何对类的调用,就已经运行了。可以打印下就知道了。这和其他几个惰性的添加属性和方法不同 。相关的可以看下菜鸟教程的java单例模式中的饿汉和饱汉,我喜欢用饱汉模式,程序启动速度快,特别是有人喜欢把io操作的结果赋值给类属性还仍然使用饿汉模式,会大幅降低程序启动速度。
关于元类的理解,就是创建类的类,默认是有type类来创建所有类。用的时候把普通类想象成实例,元类想象成类,这样就能脑袋转过弯使用他了。
所以元类可以影响类的__dict__,但影响不了实例的__dict__。
2、装饰器版本,没啥好说的了,给类添加属性
3、继承版本,很普通的,和mixin版本代码都一模一样。继承是is的关系,mixin是can的关系,mixin充当的功能应该类似于java的接口,但带了方法实现。
比如动物类,有猪、燕子、麻雀,这三个都可以继承动物类,燕子和麻雀除了可以继承动物类,还可以继承一个有飞行方法的mixin类。猪就不要继承这个mixin了。燕子是动物,燕子能够飞行,但燕子不是飞行。is can或者has的概念。
除这四种方式外,还有组合的方式加属性,见(二)
反对极端面向过程编程思维方式,喜欢面向对象和设计模式的解读,喜欢对比极端面向过程编程和oop编程消耗代码代码行数的区别和原因。致力于使用oop和36种设计模式写出最高可复用的框架级代码和使用最少的代码行数完成任务,致力于使用oop和设计模式来使部分代码减少90%行,使绝大部分py文件最低减少50%-80%行的写法。