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的概念。

除这四种方式外,还有组合的方式加属性,见(二)

原文地址:https://www.cnblogs.com/ydf0509/p/9211521.html