偶然看了一下python的部分源代码,感觉python的作者写的代码真心很美,简洁美观,学习之。

举几个例子抛砖引玉一下:

def removedirs(name):
"""removedirs(path) Super-rmdir; remove a leaf directory and all empty intermediate
ones. Works like rmdir except that, if the leaf directory is
successfully removed, directories corresponding to rightmost path
segments will be pruned away until either the whole path is
consumed or an error occurs. Errors during this latter phase are
ignored -- they generally mean that a directory was not empty. """
rmdir(name)
head, tail = path.split(name)
if not tail:
head, tail = path.split(head)
while head and tail:
try:
rmdir(head)
except error:
break
head, tail = path.split(head)

这个函数的英文解释:删除一个空的目录,也就是一个空的文件夹,注意文件夹必须是空的,不能有子文件夹,也不能有子文件,否则会报错。它是os.rmdir()方法的加强版,os.rmdir()作用是删除一个空的目录,仅此而已,但是os.removedirs()方法删除了当前的目录后,会试着去删除它的上一级目录,如果是空的,就继续删除,否则停止,说明上级目录是非空的。

分析源码:首先rmdir(name)删除给定的空目录,通过path.split(name)得到它的上级目录,主要是下面的while循环,每次都会尝试删除head,即上级目录,直到上级目录非空。

 def walk(top, topdown=True, onerror=None, followlinks=False):
"""Directory tree generator. For each directory in the directory tree rooted at top (including top
itself, but excluding '.' and '..'), yields a 3-tuple dirpath, dirnames, filenames dirpath is a string, the path to the directory. dirnames is a list of
the names of the subdirectories in dirpath (excluding '.' and '..').
filenames is a list of the names of the non-directory files in dirpath.
Note that the names in the lists are just names, with no path components.
To get a full path (which begins with top) to a file or directory in
dirpath, do os.path.join(dirpath, name). If optional arg 'topdown' is true or not specified, the triple for a
directory is generated before the triples for any of its subdirectories
(directories are generated top down). If topdown is false, the triple
for a directory is generated after the triples for all of its
subdirectories (directories are generated bottom up). When topdown is true, the caller can modify the dirnames list in-place
(e.g., via del or slice assignment), and walk will only recurse into the
subdirectories whose names remain in dirnames; this can be used to prune
the search, or to impose a specific order of visiting. Modifying
dirnames when topdown is false is ineffective, since the directories in
dirnames have already been generated by the time dirnames itself is
generated. By default errors from the os.listdir() call are ignored. If
optional arg 'onerror' is specified, it should be a function; it
will be called with one argument, an os.error instance. It can
report the error to continue with the walk, or raise the exception
to abort the walk. Note that the filename is available as the
filename attribute of the exception object. By default, os.walk does not follow symbolic links to subdirectories on
systems that support them. In order to get this functionality, set the
optional argument 'followlinks' to true. Caution: if you pass a relative pathname for top, don't change the
current working directory between resumptions of walk. walk never
changes the current directory, and assumes that the client doesn't
either. Example: import os
from os.path import join, getsize
for root, dirs, files in os.walk('python/Lib/email'):
print root, "consumes",
print sum([getsize(join(root, name)) for name in files]),
print "bytes in", len(files), "non-directory files"
if 'CVS' in dirs:
dirs.remove('CVS') # don't visit CVS directories
""" islink, join, isdir = path.islink, path.join, path.isdir # We may not have read permission for top, in which case we can't
# get a list of the files the directory contains. os.path.walk
# always suppressed the exception then, rather than blow up for a
# minor reason when (say) a thousand readable directories are still
# left to visit. That logic is copied here.
try:
# Note that listdir and error are globals in this module due
# to earlier import-*.
names = listdir(top)
except error, err:
if onerror is not None:
onerror(err)
return dirs, nondirs = [], []
for name in names:
if isdir(join(top, name)):
dirs.append(name)
else:
nondirs.append(name) if topdown:
yield top, dirs, nondirs
for name in dirs:
new_path = join(top, name)
if followlinks or not islink(new_path):
for x in walk(new_path, topdown, onerror, followlinks):
yield x
if not topdown:
yield top, dirs, nondirs

这是很常用的os.walk()函数的源代码,用了递归的方式实现的,主要理解yield,我有一篇专门介绍yield的博文。还有yield的递归使用时需要注意的。

def fab(max):
    n,a,b=0,0,1
    while n<max:
        yield b        #A
        a,b=b,a+b
        n=n+1
        
def ff(max):
    for x in fab(max):
        yield x        #B
        
for i in ff(5):
    print i
    
    上面这俩函数能解释os.walk()了。yield嵌套的执行过程:ff()函数开始执行,运行到fab()函数中A地方,返回一个b值,并且fab()函数暂停,ff函数得到这个值后,返回x,ff函数暂停;由于我们是for循环执行ff函数的,相当于执行next()函数,所以,ff函数继续执行,ff函数中也是for循环执行fab函数的,所以,fab函数继续执行,返回下一个b值,暂停,ff函数得到b值,返回x暂停,x值输出后继续执行,就是这样循环。
    结论:想要嵌套执行有yield的函数,必须用for循环来执行,得到yield返回的迭代值,必须用for循环遍历。

未完待续。。。

分析一点python源代码的更多相关文章

  1. Python源代码剖析笔记3-Python运行原理初探

    Python源代码剖析笔记3-Python执行原理初探 本文简书地址:http://www.jianshu.com/p/03af86845c95 之前写了几篇源代码剖析笔记,然而慢慢觉得没有从一个宏观 ...

  2. Python源代码目录组织结构

  3. 《python源代码剖析》笔记 Python的编译结果

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.python的运行过程 1)对python源码进行编译.产生字节码 2)将编译结果交给p ...

  4. 《python源代码剖析》笔记 Python虚拟机框架

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1. Python虚拟机会从编译得到的PyCodeObject对象中依次读入每一条字节码指令 ...

  5. 预测分析建模 Python与R语言实现

    预测分析建模 Python与R语言实现 目录 前言 第1章 分析与数据科学1第2章 广告与促销10第3章 偏好与选择24第4章 购物篮分析31第5章 经济数据分析42第6章 运营管理56第7章 文本分 ...

  6. 分析 JUnit 框架源代码

    本文转载至http://www.ibm.com/developerworks/cn/java/j-lo-junit-src/ 分析 JUnit 框架源代码 理解 JUnit 测试框架实现原理和设计模式 ...

  7. 如何打包发布加密的 Python 源代码

    这里介绍一种使用 PyInstaller 和 PyArmor 来发布加密 Python 源代码的方式,能够达到以下目的 把所有 Python 源代码打包成为可执行文件,客户不需要 Python 就可以 ...

  8. python 源代码分析之调试设置

    首先在官方下载源代码,我下载的是最新版本3.4.3版本:https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tgz 解压后的目录如下(借用网上的目 ...

  9. 《python源代码分析》笔记 pythonVM一般表达式

    本文senlie原版的.转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.字节码指令 LOAD_CONST:从consts表中读取序号为i的元素并压入到执行时栈中 ...

随机推荐

  1. Python字符串拼接、格式化输出、深浅复制

    1.Python字符串拼接:方法挺多.挺好用的.灵活使用可使代码简洁.可读性好. #1.用4种方法,将列表li = ['I','python','like'], #里面的单词拼成: I**like** ...

  2. POJ 3734 Blocks(矩阵快速幂+矩阵递推式)

    题意:个n个方块涂色, 只能涂红黄蓝绿四种颜色,求最终红色和绿色都为偶数的方案数. 该题我们可以想到一个递推式 .   设a[i]表示到第i个方块为止红绿是偶数的方案数, b[i]为红绿恰有一个是偶数 ...

  3. 精简的网站reset和css通用样式库

    一.CSS reset body{ line-height:1.4; color:#; font-family:arial; font-size: 12px; } input,textarea,sel ...

  4. 工具类_SharedPreferencesUtils

    import android.app.Application;import android.content.Context;import android.content.SharedPreferenc ...

  5. python+splinter实现12306网站刷票并自动购票流程

    python+splinter实现12306网站刷票并自动购票流程 通过python+splinter,实现在12306网站刷票并自动购票流程(无法自动识别验证码). 此类程序只是提高了12306网站 ...

  6. Java中的String、StringBuffer和StringBuilder的区别

    类型  是否可变  线程安全  能否频繁修改  String  不可变  安全  否  StringBuffer  可变  安全  能  StringBuilder  可变  不安全  能 1.可变与 ...

  7. sqlserver 常用语法

    sqlserver查找 table, view, column select * from information_schema.tables where table_schema='bk' sele ...

  8. Python练习六十:网页分析,找出里面的正文与链接

    网页分析,找出里面的正文与链接 代码如下: from urllib import request from bs4 import BeautifulSoup request = request.url ...

  9. java——斗地主小游戏之洗牌发牌

    遇到的问题: 1.int和Integer的区别? 1)Integer是int的包装类,int则是java的一种基本数据类型 . 2)Integer变量必须实例化后才能使用,而int变量不需要 . 3) ...

  10. IOS Intro - NSDictionary and NSMutableDictionary

    NSDictionary.NSMutableDictionary的基本用法 1.不可变词典NSDictionary 字典初始化 NSNumber *numObj = [NSNumber numberW ...