新手学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的相关操作

时间: 2024-10-14 12:32:47

新手学python(3):yield与序列化的相关文章

【新手学Python】一、基础篇

由于以前处理数据用Matlab和C,最近要处理大量文本文件,用C写实在是太繁琐,鉴于Python的强大文本处理能力,以及其在Deep Learning上有着很大优势,本人打算从即日起学习Python,谨以此系列博客记录学习点滴.文中如有错误,还望大牛们指出! Section 1: 本文是第一篇,当然也是基础,有了编程基础的我们都知道,学习一门语言什么最重要?当然先搞清楚数据类型和数据结构,有了这些,你才能去谈面向对象,才能去设计程序. Python的数据类型比较简单:1.整数;2.长整数;3.浮

新手学Python有什么好方法?如何学好Python?

对于新手来说,如何快速入门掌握Python编程呢?这个问题问的非常不错.学习编程来说,虽然语言具有简单化的优势,但是同样学习起来非常的麻烦,想要快速学习好一门语言,唯有站在别人的肩膀上才可以更快一些,如果学习不值得借鉴别人的经验,那么你同样会掉坑中,所以掌握高效的学习方法很重要,这些你知道吗? 大家都知道,Python是一种编程语言,可以用来做很多事情,基本可以说是全能语言了,可以用来做网站.脚本.数据分析.人工智能以及游戏开发等等,而对于很多人可能并不懂这些,只是觉得别人在学习,或者听别人说怎

新手学Python可行吗?需要什么基础吗?

Python是一门非常不错的编程语言,大家都知道该语言通俗易懂.容易上手.功能强大,可以从事多个工作领域,可以选择的岗位有很多,那么新手学习Python可以吗?需要什么基础吗?为大家介绍一下吧. 新手学习Python可以吗?当然了,其实Python可以说是非常适合新手学习的一门编程语言,难道真的不需要任何基础吗?简单的来说,如果学习者具备一定计算机基础的情况下,学习起来会更快一些的,当然了即便是没有基础,如果自己愿意付出精力和时间,同样可以学习好Python的.所以说新手学习Python是可行的

新手学python疑惑(一)—— 列表内容的复制

疑惑在于 <python 程序设计(第2版) 董付国 清华大学出版社>第46页 原文是: [列表推导式] >>>freshfruit=['banana', 'loganberry', 'passion fruit'] >>>aList=[w.strip() for w in freshfruit] 等价于下面的代码: >>>freshfruit=['banana', 'loganberry', 'passion fruit'] >&g

新手学python遇到问题。

对这段话理解如下:结果报错:是否有大牛解释一下? 原文地址:https://blog.51cto.com/12197109/2401951

运维新手们,别再问需不需要学PYTHON了!!!

经常有人在群里问,运维人员需不需要学开发?需不需要学PYTHON?PYTHON和SHELL有什么区别?天天问这种好水的问题,我实在受不了,决定帮大家扫扫盲,求求新手们,以后别他妈瞎问了.现阶段,掌握一门开发语言已经成为高级运维工程师的必备计能,不会开发,你就不能充分理解你们系统的业务流程,你就不能帮助调试.优化开发人开发的程序,开发人员有的时候很少关注性能的问题,这些问题就得运维人员来做,一个业务上线了,导致CPU使用过高,内存占用过大,如果你不会开发,你可能只能查到进程级别,也就是哪个进程占用

Python自学之旅 #新手#MacBook #《“笨办法”学Python》#第六章:常用的简易Python命令、符号、代码、格式化字符串

第六章:常用的简易Python命令.符号.代码.字符串 <“笨办法”学Python>这本书中,确实用了较多篇幅来介绍Python的一些常用简单的命令.符号.代码和字符串等,对于像我这样的自学新手,真的是非常棒,因为它们可以帮我建立接着学下去的信心和兴趣.但我在这个系列的博客当中,不打算写的这么精细,首先因为这不符合我写博的初衷和习惯,其次因为我不打算靠这写书来挣钱,最后因为我确实没有那个实力去挖掘简单东西中更深奥复杂的应用.所以,我写的这个博客,只适合像我这样的自学新手,如果想要成为大神,还是

新手从Python的哪个版本开始学比较好?

想学习Python的人都会有一个困惑,那就是Python目前有两个版本Python2和Python3,Python2与Python3有何区别,两个版本该学习哪个呢? python3 和 python2 是不兼容的,而且差异比较大,python3是不向下兼容的,但是绝大多数组件和扩展都是基于python2的.目前实际应用中大部分暂不考虑 Python3,有的时候注意写兼容 2/3 的代码.用 Python2 为主的写新代码时要考虑以后迁移到 Python3 的可能性.据数据统计显示目前10% 使用

新手小白学Python有前途吗?

最近开始整理python的资料,博主建立了一个qq群,希望给大家提供一个交流的同平台 78486745 . 很多同学在选择学习python之初,可能都有这样的疑惑:学Python有前途吗?对于新兴的事物,人们慢慢接受是需要一个过程的,那究竟学python有没有前途呢?今天小编就来给大家指导一下迷津. 首先从国家的层面上来说,国务院发布<新一代人工智能发展规划>,人工智能正式纳入国家发展战略,在教育上,教育部已将人工智能.物联网.大数据处理划入高中新课标;浙江省.北京市.山东省等将 Python