Python 中的 Decorator 大家见得多了,但 Descriptor 用过的估计还少,它主要是 Python 自身来实现库的一些特性,比如 staticmethod 之类的,今天有机会学习、试验了 Descriptor,小有所得,跟大家分享。

今天 Jeff 给我们出了一道难题:有个叫 data 的某个 class 的实例,它有一个 item 属性,它可能是一个对象(姑且假设它是个 str object),也可能是一序列对象(比如 list object),在这个前题下,希望做到以下代码能够工作:

# 当 data.item 是一个序列 data.item = ['lai', 'yong', 'hao'] print(data.item) # output: ['lai', 'yong', 'hao'] for i in data.item: print i # output: lai yong hao # 当 data.item 是单个元素 data.item = 'lai' print(data.item) # output: lai for i in data.item: print i # output: lai

如果你现在觉得没啥,那肯定是没看仔细。我来提醒一下你,最后一行的 output 居然不是 lai 三个字母分成三行!

也就是说 data.item 要做到当它是单个元素的时候,普通场合要跟单元元素一样,而迭代的场合,要跟包含多个元素的序列一样!这个要求太变态了。这么有挑战的问题,我马上祭出 python documentation,天不负苦心人,我找到了 Descriptor 这个我以前从未使用过的特性,最后解决了这个问题。详情多讲无益,直接上代码:

#!/usr/bin/env python # -*- coding:utf-8 -*- from __future__ import print_function class ItemDescriptor(object): def __init__(self): self._data = [] def __get__(self, instance, type = None): if len(self._data) == 1: tmp = self._data[0] class Wrapper(tmp.__class__): # 注意它的父类 def __iter__(obj): # 这里使用的是 obj 不是 self,因为 self 已经被用了 return self._data.__iter__() def next(obj): return self._data.next() return Wrapper(tmp) return self._data def __set__(self, obj, val): if isinstance(val, list): self._data = val return self._data = [val] class Foo(object): item = ItemDescriptor() # 重要! foo = Foo() # 输出 Jeff,而不是 Jeff 一个字母一行 foo.item = 'Jeff' print(foo.item) # 它的行为跟 'Jeff' 一样 print('f' in foo.item) # 但迭代的时候,像 ['jeff'] 一样 for i in foo.item: print(i) # 输出四行单词,而不是一行 :) foo.item = ['lai', 'pan', 'jeff', 'ken'] print(foo.item) # 它的行为像 ['lai', 'pan', 'jeff', 'ken'] 一样 print('ken' in foo.item) # 迭代时行为也像 ['lai', 'pan', 'jeff', 'ken'] 一样 for i in foo.item: print(i) print('#' * 30)

输出:

lai@sd:~$ python test_descriptor.py Jeff True Jeff ['lai', 'pan', 'jeff', 'ken'] True lai pan jeff ken ##############################

最后,多说一句这些代码在 py2.6 和 py3.1 下测试通过,兼容两大版本。

用 Python 的 Descriptor 特性解决一个变态的问题相关推荐

  1. python中接口测试垃圾数据如何清理_巧用PyUnit中unittest特性解决接口测试产生脏数据问题...

    巧用PyUnit中unittest特性解决接口测试产生脏数据问题 一.背景 测试数据创建后需要对其删除,不然可能产生脏数据,对开发和测试.生产环境造成一定影响.其接口框架是基于Python,API规范 ...

  2. ACMNO.27 Python的两行代码解决 C语言-字符逆序 写一函数。使输入的一个字符串按反序存放,在主函数中输入输出反序后的字符串。 输入 一行字符 输出 逆序后的字符串

    题目描述 写一函数,使输入的一个字符串按反序存放,在主函数中输入输出反序后的字符串. 输入 一行字符 输出 逆序后的字符串 样例输入 123456abcdef 样例输出 fedcba654321 来源 ...

  3. python面向对象——三大特性

    python面向对象--三大特性 1. 引言 Python是面向对象的语言,自然也支持面向对象的三大特性:封装.继承.多态. 因为Python2已经较为古老,所有除非是阐述区别,大部分情况下Pytho ...

  4. python运行非常慢的解决-python执行太慢

    广告关闭 腾讯云双11爆品提前享,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高满返5000元! 假如 load 完成还没计算,这时候线程切换了,其他线程修改了 a 的值,然后切换 ...

  5. python实现支持向量机实例_一个简单的案例带你了解支持向量机算法(Python代码)...

    介绍 掌握机器学习算法并不是一个不可能完成的事情.大多数的初学者都是从学习回归开始的.是因为回归易于学习和使用,但这能够解决我们全部的问题吗?当然不行!因为,你要学习的机器学习算法不仅仅只有回归! 把 ...

  6. python工程师怎么考-【一个合格的Python工程师需要达到怎样的编程水平】

    如何才算精通Python?在Python学习中,我们都有哪些误区?相信你看完这篇文章都会得到解答. 如果不能,我希望这篇回答能让你意识到自己Python知识还存在哪些不足,在之后的学习中,从哪些方面去 ...

  7. 太简单!只学十分钟,Python菜鸟也能开发一个区块链客户端

     区块链技术以其去中心化特性成为又一具有颠覆性特征的技术.Python作为一种面向对象的解释型计算机程序设计语言,因其具有丰富和强大的库,常被称为"胶水语言",简单.易上手,是区 ...

  8. 2.1.1 Python面向对象三大特性

    点击跳转Python笔记总目录 Python面向对象三大特性 1,继承 1,继承和组合 组合 继承 2,封装 2.0 私有变量和私有方法 2.1 封装与扩展性 2.2 property属性 2.3 c ...

  9. python -- 面向对象三大特性

    1,继承 1,初识继承 什么是继承? --继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类. 子类会"遗传&quo ...

最新文章

  1. BIOS, UEFI, MBR, GPT, GRUB介绍
  2. 内存溢出分析之工具篇
  3. MySQL 字段数据类型/长度
  4. idea启动多个tomcat失败
  5. openresty获取nginx 请求方法
  6. AChartEngine中的Renderer和DataSet介绍
  7. 多图文帖智能封面提取方案
  8. dedecms二次开发常用代码
  9. linux下移动或者复制文件覆盖相同文件夹时,文件夹里面的每个文件都提示是否覆盖...
  10. cocos2d-x-3.x 配置(1)win环境搭建
  11. Linux应用调试-strace命令
  12. Window下完全卸载MySQL教程
  13. 《云计算与大数据技术应用》
  14. PHP常用函数集合(可做桌面壁纸)
  15. android自动刷广告软件是,自动刷视频挂机下载-自动刷视频软件下载1.0安卓版-西西软件下载...
  16. php fpm 报错,php-fpm报错
  17. 3DMark03 测试显卡
  18. 免拆机,Kindle固件版本5.10.3~5.13.3如何越狱?简单、易操作版
  19. 点线面的意义_点线面在绘画中的意义
  20. 微型计算机芯片上的位数,微处理器芯片的位数指的是什么

热门文章

  1. 直流无刷减速电机PID控制
  2. 怎么把图片文件大小压缩到25k到40k还比较清晰
  3. 金钥匙信息管理系统说明文档
  4. Hallo小程序应用在山东为何能那么短时间内暴发
  5. wifi卡慢延迟高_卡顿缓冲真头疼 这几招能加速你的WiFi
  6. 过去的金三银四百度、小米、字节、蚂蚁金服等大厂Java面试总结
  7. JWT Token在线解析解码
  8. dubbo框架及dubbo环境搭建
  9. 使用Verilog设计1553B总线协议芯片
  10. 下坠的优信:全国购失灵了?