python3源代码分析_分析一点python源代码

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

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

defremovedirs(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 nottail:

head, tail=path.split(head)while head andtail:try:

rmdir(head)excepterror:breakhead, tail= path.split(head)

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

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

1 def walk(top, topdown=True, οnerrοr=None, followlinks=False):2 """Directory tree generator.3

4 For each directory in the directory tree rooted at top (including top5 itself, but excluding '.' and '..'), yields a 3-tuple6

7 dirpath, dirnames, filenames8

9 dirpath is a string, the path to the directory. dirnames is a list of10 the names of the subdirectories in dirpath (excluding '.' and '..').11 filenames is a list of the names of the non-directory files in dirpath.12 Note that the names in the lists are just names, with no path components.13 To get a full path (which begins with top) to a file or directory in14 dirpath, do os.path.join(dirpath, name).15

16 If optional arg 'topdown' is true or not specified, the triple for a17 directory is generated before the triples for any of its subdirectories18 (directories are generated top down). If topdown is false, the triple19 for a directory is generated after the triples for all of its20 subdirectories (directories are generated bottom up).21

22 When topdown is true, the caller can modify the dirnames list in-place23 (e.g., via del or slice assignment), and walk will only recurse into the24 subdirectories whose names remain in dirnames; this can be used to prune25 the search, or to impose a specific order of visiting. Modifying26 dirnames when topdown is false is ineffective, since the directories in27 dirnames have already been generated by the time dirnames itself is28 generated.29

30 By default errors from the os.listdir() call are ignored. If31 optional arg 'onerror' is specified, it should be a function; it32 will be called with one argument, an os.error instance. It can33 report the error to continue with the walk, or raise the exception34 to abort the walk. Note that the filename is available as the35 filename attribute of the exception object.36

37 By default, os.walk does not follow symbolic links to subdirectories on38 systems that support them. In order to get this functionality, set the39 optional argument 'followlinks' to true.40

41 Caution: if you pass a relative pathname for top, don't change the42 current working directory between resumptions of walk. walk never43 changes the current directory, and assumes that the client doesn't44 either.45

46 Example:47

48 import os49 from os.path import join, getsize50 for root, dirs, files in os.walk('python/Lib/email'):51 print root, "consumes",52 print sum([getsize(join(root, name)) for name in files]),53 print "bytes in", len(files), "non-directory files"54 if 'CVS' in dirs:55 dirs.remove('CVS') # don't visit CVS directories56 """

57

58 islink, join, isdir =path.islink, path.join, path.isdir59

60 #We may not have read permission for top, in which case we can't

61 #get a list of the files the directory contains. os.path.walk

62 #always suppressed the exception then, rather than blow up for a

63 #minor reason when (say) a thousand readable directories are still

64 #left to visit. That logic is copied here.

65 try:66 #Note that listdir and error are globals in this module due

67 #to earlier import-*.

68 names =listdir(top)69 excepterror, err:70 if onerror is notNone:71 onerror(err)72 return

73

74 dirs, nondirs =[], []75 for name innames:76 ifisdir(join(top, name)):77 dirs.append(name)78 else:79 nondirs.append(name)80

81 iftopdown:82 yieldtop, dirs, nondirs83 for name indirs:84 new_path =join(top, name)85 if followlinks or notislink(new_path):86 for x inwalk(new_path, topdown, onerror, followlinks):87 yieldx88 if nottopdown:89 yield top, dirs, nondirs

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

def fab(max):

n,a,b=0,0,1

while n

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循环遍历。

未完待续。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值