用 Python 遍历目录、清空临时文件

  前几天由于调试时需要频繁的清空临时文件夹,同事给了我一个他用 Python 写的脚本,目录及文件遍历用的是 os.walk(),后来在查文档的时候又发现了一个 os.path.walk(),Google 了一下,据说 os.walk() 是 Python 2.3 中才增加的,之前只有 os.path.walk()。但是从 Python 3.0 的文档来看,os.path.walk() 已经被废止了,只剩下 os.walk()。

  但是 os.walk() 用起来比较不顺手,不能像 Windows API 那样递归的进行目录树遍历,而是一次性的扔给你某路径下的所有文件和子目录。查了查文档,用 os.listdir() 实现了递归式层层深入的目录和文件遍历:

  1. import os, stat
  2.  
  3.  def WalkDir( dir, dir_callback = None, file_callback = None ):
  4.      for item in os.listdir( dir ):
  5.          fullpath = dir + os.sep + item
  6.          if os.path.isdir( fullpath ):
  7.              WalkDir( fullpath, dir_callback, file_callback )
  8.              if dir_callback: dir_callback( fullpath )
  9.          else:
  10.              if file_callback: file_callback( fullpath )

由于发现目录时会首先递归调用 WalkDir() 自己,然后再给目录 callback 一个执行机会,所以这算是一个深度优先的遍历实现,调用 WalkDir() 时传入相应的目录回调和文件回调就可以实现特定的功能,我利用刚刚实现的基础设施重新实现了一个清空临时文件夹的脚本:

  1. def DeleteDir( dir ):
  2.      try:
  3.          os.rmdir( dir )
  4.      except WindowsError, e:
  5.          print( "Can't delete directory " + dir + ", err = " + str( e.winerror ) )
  6.  
  7.  def DeleteFile( file ):
  8.      try:
  9.          os.unlink( file )
  10.      except WindowsError, e:
  11.          if 32 == e.winerror:
  12.              print( "Can't delete " + file + ", err = " + str( e.winerror ) )
  13.          elif 5 == e.winerror:
  14.              os.chmod( file, stat.S_IWRITE )  # Try to remove readonly attribute
  15.              try:
  16.                  os.unlink( file )  # Try again
  17.              except WindowsError, e:
  18.                  print( "Can't delete " + file + ", err = " + str( e.winerror ) )
  19.  
  20.  WalkDir( os.environ['TEMP'], DeleteDir, DeleteFile )

  最近抽时间看了些 Python 的电子文档,经常写些练手的小东西,以后打算拿这个做日常使用的脚本语言。至于 PHP,还是在 Web 领域比较专精和适用。

[2011/09/14 Update]
“del /f /s /q %temp%”可以部分替代上述 Python 脚本,缺点是不能删除空目录。

2 Responses to “用 Python 遍历目录、清空临时文件”

  1. BOYPT Says:

    os.walk的存在就是为了避免让程序员写需要递归的代码,使用os.walk等价版WalkDir:

    def WalkDir( dir, dir_callback = None, file_callback = None ):
    for root, dirs, files in os.walk(dir):
    for f in files:
    file_path = os.path.join(root, f)
    if file_callback: file_callback( file_path )
    for d in dirs:
    dir_path = os.path.join(root, d)
    if dir_callback: dir_callback( dir_path )

  2. 2ndboy Says:

    谢谢留言:)

Leave a Reply