介绍装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式

有时候需要給类添加额外的东西,有些东西很频繁,每个类都需要,如果不想反复的复制粘贴到每个类,可以动态添加。

 # 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装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式(一)的更多相关文章

  1. 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间

    [源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...

  2. 第六种方式,python使用cached_property缓存装饰器和自定义cached_class_property装饰器,动态添加类属性(三),selnium webdriver类无限实例化控制成单浏览器。

    使用 from lazy_object_proxy.utils import cached_property,使用这个装饰器. 由于官方的行数比较少,所以可以直接复制出来用自己的. class cac ...

  3. Python 装饰器装饰类中的方法

    title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...

  4. python 装饰器的理解以及类装饰器

    python装饰器的作用就是在不改变原有函数结构的情况下给该函数增加一个新功能,就是不入侵到原来函数里面修改代码给其增加一个新功能 先看代码 def out(fn): def inner(*args, ...

  5. Python装饰器实现类Java注解功能

    最近想用Python写一个简单生成器,类似指定类型和范围,返回指定列表: 比如想要  0 ~ 3 的整数,则 我只需要指定: 最小:0, 最大:3, 步长:1 则返回一个 [0,1,2,3] 的列表 ...

  6. 粗浅聊聊Python装饰器

    浅析装饰器 通常情况下,给一个对象添加新功能有三种方式: 直接给对象所属的类添加方法: 使用组合:(在新类中创建原有类的对象,重复利用已有类的功能) 使用继承:(可以使用现有类的,无需重复编写原有类进 ...

  7. python 装饰器 一篇就能讲清楚

    装饰器一直是我们学习python难以理解并且纠结的问题,想要弄明白装饰器,必须理解一下函数式编程概念,并且对python中函数调用语法中的特性有所了解,使用装饰器非常简单,但是写装饰器却很复杂.为了讲 ...

  8. python装饰器,迭代器,生成器,协程

    python装饰器[1] 首先先明白以下两点 #嵌套函数 def out1(): def inner1(): print(1234) inner1()#当没有加入inner时out()不会打印输出12 ...

  9. Python 装饰器学习

    Python装饰器学习(九步入门)   这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...

随机推荐

  1. gdb基本命令(非常详细)

    gdb基本命令 本文介绍使用gdb调试程序的常用命令. 主要内容: [简介] [举例] [其他] [简介] ============= GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具. ...

  2. JDK观察者模式和事件机制比较<转>

    原文:(六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型) 作者:zuoxiaolong8810(左潇龙),转载请注明出处. 本章我们讨论一个除前面的单例以及代理模式之外,一个WEB项目 ...

  3. sql 拼接同列的值

    sql中有时需要将列的值转成行的形式,比如下面的数据,具有相同Path的ZumenID有哪一些,该怎么做呢? 常见的做法可以参见这篇文章http://www.cnblogs.com/xiashengw ...

  4. Spring Cloud Config 自动刷新所有节点 架构改造

    详细参考:<Sprin Cloud 与 Docker 微服务架构实战>p162-9.9.4节 要做的改动是: 1.在spring cloud config server 服务端加入 spr ...

  5. 自定义垂直拖动的seekbar进度条

    系统自定义的seekbar为横向拖动的样式,需要纵向的时则需要自己定义,网上很多说了重写系统SeekBar中onDraw()的方法,但是我使用的时候不知道为什么拖动条和点偏离了,不在一条直线上,好气. ...

  6. javascript小技巧[转]

    总的来说,如果你要找js 的东西,而不看这两篇的话,肯定要多花好多时间!!哈哈!! 如果你找的javascript的东西的话,建议你 ctrl+F  直接在这个页上找,因为这里80%有你要找的,但是要 ...

  7. Android学习之发送及接收广播

    1.使用标准广播 1.1 定义广播接收器 public class MyBroadcastReceiver extends BroadcastReceiver { @Override public v ...

  8. 解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)

    一.Qt环境设置 文件从window上传到Ubuntu后会显示乱码,原因是因为ubuntu环境设置默认是utf-8,Windows默认都是GBK.Windows环境下,Qt Creator,菜单-&g ...

  9. Mac eclipse 编译、调试c++ 程序

    可以先安装个CDT插件: eclipse菜单 -> Help -> Install New Software... -> Work with (Add..) Name:CDT Loc ...

  10. python3 pyodbc简单使用

    转自:https://my.oschina.net/zhengyijie/blog/35587 1.连接数据库 首先要import pyodbc 1)直接连接数据库和创建一个游标(cursor) cn ...