首页 技术 正文
技术 2022年11月15日
0 收藏 803 点赞 2,306 浏览 4194 个字

偶然看了一下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开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,000
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,512
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,358
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,141
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,771
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,849