新手学python(3):yield与序列化
1 Yield生成器
Yield是我在其他语言中没有见过的一个属性,算是python的一大特色,用好之后可以使代码更简洁。考虑一个简单的例子,文件的遍历。要遍历一个目录下的所有文件需要递归的操作。如果我们只是单纯的打印文件名,我们可以在递归的过程中完成,每当发现一个非目录就可以打印文件名。代码如下:
class TraverseDirectory(object):
@staticmethod
def traverse(dir):
if os.path.isdir(dir):
files=os.listdir(dir);
for file in files[::-1]:
full_name=os.path.join(dir,file);
TraverseDirectory.traverse(full_name):
else:
print dir;
但是如果我们想保存文件名或者对每一个文件执行更复杂的操作返回一个结果,情况就稍微有些复杂。问题在于我们需要一个全局变量保存访问的结果。例如在遍历到一个文件时获取其文件大小,则我们还需要一个dictionary结构:
class TraverseDirectory(object):
fileSize=dict();
@staticmethod
def traverse(dir):
if os.path.isdir(dir):
files=os.listdir(dir);
for file in files[::-1]:
full_name=os.path.join(dir,file);
TraverseDirectory.traverse(full_name);
else:
TraverseDirectory.fileSize[dir]=os.path.getsize(dir);
初看代码感觉其实也不复杂,只是多了一个变量而已。在多数情况下确实如此,但是从应用角度来看上述代码稍有不足:为了访问遍历的结果,我们需要访问该类的全局变量或者一个静态变量,正如我们在其他语言中一样,为此我们还需要一个get函数。但是,这还不是最严重的问题,fileSize占用的空间才是问题!
上述递归函数只有在遍历完所有的文件之后我们才能访问fileSize结构。这就意味着如果目录很大,则fileSize也会非常大,如果要控制内存占用,上述方式会很不好。此时,就可以采用yield生成器完成遍历。
何谓生成器?其实很简单,概念和迭代器类似,都是为了遍历而存在。迭代器是为了遍历变量,例如列表、元组、字典等等。生成器不是遍历变量,而是函数。简而言之,包含yield语句的函数会被特地编译成生成器。当函数被调用时,他们返回一个生成器对象,这个对象支持迭代器接口。不像一般的函数会生成值后退出,生成器函数在生成值后会自动挂起并暂停他们的执行和状态,他的本地变量将保存状态信息,这些信息在函数恢复时将再度有效。我们可以将生成器理解成可以随时获得函数返回值的迭代器。可以将生成器与gdb调试器对比,我们在每一步单步调试的过程中,系统中总会有许多变量和其运行时值,yield就对应每一次的单步调试,并获取当前的变量值,不过其获取返回值是在每一次递归结束时。将上述遍历代码改成yield方式之后为:
class TraverseDirectory(object):
@staticmethod
def traverse(dir):
if os.path.isdir(dir):
files=os.listdir(dir);
for file in files[::-1]:
full_name=os.path.join(dir,file);
for results in TraverseDirectory.traverse(full_name):
yield results;
else:
yield {dir:os.path.getsize(dir)};
与之前的代码相比,就是少了一个变量,然后多了两个yield。通过这个微小的变化,我们去掉了函数的内存大小限制,也使代码更简洁。需要注意的一点是,调用过程也很简单,因为函数是一个生成器,具有迭代器的功能,我们就可以利用for循环去遍历函数的返回值。
Yield这种具有中断功能的设计使代码更加简洁,但是对效率会有一定影响。瑕不掩瑜,建议大家熟练应用yield。
2 序列化
在进行网络通信的过程中,我们传递的是没有含义的数据流,这就意味着我们无法直接传递list和dict之类的数据结构,而需要首先将它们序列化之后再进行传递。接收方收到数据流之后再发序列化获得原始的数据结构。序列化的应用并不局限于网络通信,在持久化存储中也需要用到序列化。
Python中有两个关于序列化的库:json和cPickle,两者用法相同,但是貌似json速度更快,因而json使用的次数更多。序列化调用dumps,反序列化调用loads,使用非常简单。
如果需要序列化的数据编码方式不是默认方式,我们还可以指定编码方式:
result=json.dumps(data,ensure_ascii=True,encoding=’gbk’);
反序列化也需要指定编码方式:
result=json.loads(data, encoding=’gbk’);
由于序列化操作在python中非常简单,在此不做更多介绍,更加深入的操作请参考:Json概述以及python对json的相关操作。
新手学python(3):yield与序列化的更多相关文章
- 【新手学Python】一、基础篇
由于以前处理数据用Matlab和C,最近要处理大量文本文件,用C写实在是太繁琐,鉴于Python的强大文本处理能力,以及其在Deep Learning上有着很大优势,本人打算从即日起学习Python, ...
- 新手学python(1):解析XML与系统调用
最近需要做一个项目,完成一批音乐的格式转换.由于之前并未学习过python,所以想借此机会学一下.在介绍自己的学习过程之前,先把项目简要描述一下.目前在一台服务器a上有几十万首原始的MP3音乐文件,现 ...
- 新手学python(2):C语言调用完成数据库操作
继续介绍本人的python学习过程.本节介绍如何利用python调用c代码.内容还是基于音乐信息提取的过程,架构如图一.Python调用c实现的功能是利用python访问c语言完成mysql数据库操作 ...
- 零基础怎么学Python编程,新手常犯哪些错误?
Python是人工智能时代最佳的编程语言,入门简单.功能强大,深获初学者的喜爱. 很多零基础学习Python开发的人都会忽视一些小细节,进而导致整个程序出现错误.下面就给大家介绍一下Python开发者 ...
- 简学Python第二章__巧学数据结构文件操作
#cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ...
- 简学Python第一章__进入PY的世界
#cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ...
- 小白学PYTHON时最容易犯的6个错误,看看你遇到过几个
最近又在跟之前的同学一起学习python,一起进步,发现很多测试同学在初学python的时候很容易犯一些错误,特意总结了一下.其实这些错误不仅是在学python时会碰到,在学习其他语言的时候也同样会碰 ...
- [ZZ]新手学 appium-合集第一季度
原文地址: https://testerhome.com/topics/2599 新手学appium-合集第一季度地址如下: 1.新手学 appium-GUI 端搞起来:http://testerho ...
- 投入机器学习的怀抱?先学Python吧
前两天写了篇文章,给想进程序员这个行当的同学们一点建议,没想到反响这么好,关注和阅读数都上了新高度,有点人生巅峰的感觉呀.今天趁热打铁,聊聊我最喜欢的编程语言——Python. 为什么要说Python ...
随机推荐
- 第一节mysql 安装
1 安装之前的检查 先要检查Linux系统中是否已经安装了MySQL,输入命令尝试打开MySQL服务: 输入密码后,如果出现以下提示,则说明系统中已经安装有 MySQL: 如果提示是这样的,则说明系统 ...
- HashMap实现原理和源码解析
哈希表(hash table)也叫散列表,是一种非常重要的数据结构.许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,本文会对java集合框架中的对应实现HashMap的 ...
- VMWare 学习目录
Linux介绍 Linux入门--个人感想 Google怎么用linux 初入Linux Windows XP硬盘安装Ubuntu 12.04双系统图文详解 实例讲解虚拟机3种网络模式(桥接.nat. ...
- mybatis添加记录时返回主键id
参考:mybatis添加记录时返回主键id 场景 有些时候我们在添加记录成功后希望能直接获取到该记录的主键id值,而不需要再执行一次查询操作.在使用mybatis作为ORM组件时,可以很方便地达到这个 ...
- 欢迎大家来到DevLegal的博客
申明:以下博文欢迎转载,转载请注明出处和作者 若非作者原创,则会标记出处与原作者,其余则为原创. 本人在校大学僧一枚,软件工程专业,希望通过将自己的学习心得与体会写出来,勉励自己学习,同时与大家一起分 ...
- html下载excel模板
只需要href等于模板存放的路径即可 <a href="../../TempLate/Attitude.xlsx" class="easyui-linkbutton ...
- linux加入Windows域-------本人生产环境上线所用
为什么说要linux加域呢! 因为之前在公司是做vmware的,然后呢vmware的horizon桌面云虚拟化都是通过域来管理的,开始使用的都是Windows桌面,后来开发的人员说要使用linu ...
- Git/GitHub SSH配置
生成 SSH 公钥 如前所述,许多 Git 服务器都使用 SSH 公钥进行认证. 为了向 Git 服务器提供 SSH 公钥,如果某系统用户尚未拥有密钥,必须事先为其生成一份. 这个过程在所有操作系统上 ...
- Docker学习系列(二)Docker初体验
一.系统要求 Docker的安装,需要在CentOS 7.0+版本,内核至少3.10,64-bit uname --r [randy@randysun ~]$ uname --r -.el7.x86_ ...
- DotnetSpider (二) Downloader的设置 Request自定义数据字典
本篇主要分享自定义Downloader和Request信息,实现自定义请求内容,及将自定义内容存储. ** 温馨提示:如需转载本文,请注明内容出处.** 本文连接:http://www.cnb ...