python装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式(一)
2018-06-21 23:59
211 查看
介绍装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式
有时候需要給类添加额外的东西,有些东西很频繁,每个类都需要,如果不想反复的复制粘贴到每个类,可以动态添加。
这样就完成了给类添加属性和方法了。
A类什么都不写,a的实例就有4个自定义的方法和4个属性了。
1、其中,元类,是在代码不进行任何对类的调用,就已经运行了。可以打印下就知道了。这和其他几个惰性的添加属性和方法不同 。相关的可以看下菜鸟教程的java单例模式中的饿汉和饱汉,我喜欢用饱汉模式,程序启动速度快,特别是有人喜欢把io操作的结果赋值给类属性还仍然使用饿汉模式,会大幅降低程序启动速度。
关于元类的理解,就是创建类的类,默认是有type类来创建所有类。用的时候把普通类想象成实例,元类想象成类,这样就能脑袋转过弯使用他了。
所以元类可以影响类的__dict__,但影响不了实例的__dict__。
2、装饰器版本,没啥好说的了,给类添加属性
3、继承版本,很普通的,和mixin版本代码都一模一样。继承是is的关系,mixin是can的关系,mixin充当的功能应该类似于java的接口,但带了方法实现。
比如动物类,有猪、燕子、麻雀,这三个都可以继承动物类,燕子和麻雀除了可以继承动物类,还可以继承一个有飞行方法的mixin类。猪就不要继承这个mixin了。燕子是动物,燕子能够飞行,但燕子不是飞行。is can或者has的概念。
除这四种方式外,还有组合的方式加属性,见(二)
有时候需要給类添加额外的东西,有些东西很频繁,每个类都需要,如果不想反复的复制粘贴到每个类,可以动态添加。
# coding=utf-8 def create_class_attribution(cls): def _inner(*args, **kwargs): if not hasattr(cls, 'xx'): cls.xx = 1 def funa(self, a, b): return a + b if not hasattr(cls, 'funa'): cls.funa = funa return cls(*args, **kwargs) return _inner class Base(): # __metaclass__ = Meta def __new__(cls, *args, **kwargs): if not hasattr(cls, 'yy'): cls.yy = 2 return super().__new__(cls) def funb(self, a, b): return a + b class MyType(type): def __new__(cls, name, bases, attrs): attrs['zz'] = 3 attrs['func'] = lambda self, a, b: a + b return super(MyType, cls).__new__(cls, name, bases, attrs) class MyMixin(): def __init__(self, *args, **kwargs): if not hasattr(self, 'ww'): self.__class__.ww = 4 def fund(self, a, b): return a + b @create_class_attribution class A(MyMixin, Base, metaclass=MyType): pass a = A() print (a.xx) print (a.yy) print (a.zz) print (a.ww) print (a.funa(1, 2)) print (a.funb(3, 4)) print (a.func(5, 6)) 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的概念。
除这四种方式外,还有组合的方式加属性,见(二)
相关文章推荐
- 我的Python学习笔记(四):动态添加属性和方法
- android Kotlin 继承、派生、接口、构造方式,方法、属性重写
- c# 对象运行时动态添加属性、方法
- javascript动态添加、修改、删除对象的属性和方法
- spring ioc容器注入的集中方式,以及属性注入的集中依赖,继承,使用SPEL表达式,ioc容器的生命周期,bean的几种工厂方法配置方式,bean的自动装配
- groovy运行期间动态添加属性和方法
- runtime 系列-1.动态添加类及类属性 4000 ,并为类动态添加方法
- JavaScript可以动态添加、删除对象属性与方法
- JS动态给对象添加属性和值的实现方法
- 第五种方式,python使用组合来添加类方法和属性(二),以selenium的webdriver为例
- JavaScript原形继承方式添加自定义格式化方法
- 【原】iOS动态性(一):动态添加属性的方法——关联(e.g. 向Category添加成员变量)
- Runtime-动态创建类添加属性和方法
- 面向对象---基于组合的继承:属性的继承基于伪装的方式实现,而方法的继承基于原型链的方式继承。
- JavaScript 中实现继承的方式(列举3种在前一章,我们曾经讲解过创建类的最好方式是用构造函数定义属性,用原型定义方法。)
- Runtime-动态创建类添加属性和方法
- JavaScript中定义对象的方式,动态添加属性和动态删除属性!
- javascript动态添加、修改、删除对象的属性与方法详解
- Javascript 创建类并动态添加属性及方法
- 【CSS样式层叠表】:position属性|static|absolute|relative|fix|四种控制方式的使用方法