介绍装饰器、继承、元类、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. [dig]使用dig查看当前网络连通情况

    1. dig domain, 通过server可以查到该域名被哪个server给解析了 2. dig @dns domain 不走/etc/resolve.conf,直接走指定的dns ------- ...

  2. Android——远程存储器存储:JDK方式和Volley框架的get和post

    注意:要搭建好环境,运行 用volley方法时要把包导入project下的模块下的libs目录下 package com.example.chenshuai.myapplication; import ...

  3. 批量修改mysql数据库引擎

    数据库表中部分是MyISAM引擎,部分是InnoDB.由于MyISAM不支持事务,所以需要全部修改为InnoDB引擎. (下面例子SQL语句中 ecsoft 为数据库名) 通过以下查询可以看到数据库中 ...

  4. 处理异常json串的jar包JsonSerde

    参考下面文章: https://blog.csdn.net/SunnyYoona/article/details/70170173

  5. js 控制输入文字个数(换行不算)

    如题,换行符在textarea中是要当成一个字符的.用普通的maxlength属性就不行了,于是想到通过事件来控制输入文字的长度. 注意哦,回车换行不能算成字符.这样的话,普通的substring等方 ...

  6. linux下查看cpu物理个数和逻辑个数

    hadoop@chw-desktop3:~$ cat /proc/cpuinfo processor   : 0 vendor_id   : GenuineIntel cpu family  : 15 ...

  7. Hbase 学习(六) 配置文件调优

    这部分的内容,网上多了去了,都大同小异的,仅作为备忘录,省得需要的时候又要到处查. 1.zookeeper.session.timeout 默认3分钟,zookeeper和hbase通信的超时时间,设 ...

  8. 两个项目之间通过 RestTemplate 进行调用

    A服务发出请求: @RequestMapping("/jqgridjsondata.json") @ResponseBody public String jqgridJsonDat ...

  9. git 通过nginx 无法clone

    git服务器架设在内网,通过nginx做反向代理后如果公网质量差的话部分项目无法clone,报错: error: RPC failed; result=18, HTTP code = 200B | 3 ...

  10. Eclipse下进行SVN提交时报“svn: 过期”错误的解决办法

    http://www.thinksaas.cn/group/topic/105323/ ———————————————————————————————————————————————————————— ...