2011-09-25 22 views
4

我想要shutil的copytree函數提供的忽略模式。我希望src樹替換dest目錄中的所有現有文件/文件夾,例如distutil.dir_util.copy_tree。(distutil + shutil)* copytree =?

我是一個相當新的Python用戶,似乎無法找到任何這方面的文章。

+0

有趣。你的問題是什麼? – knitti

+0

生命的意義是什麼? Hehe jk。 – Michael

+0

我想你使用複製樹函數,它們都替換了現有的文件/目錄,並且可以採用忽略模式。 shutils和distutils每個都有我想要的一半功能。 – Michael

回答

3

我打算說這個耳朵,但我沒有。 http://docs.python.org/library/shutil.html有一個版本的copytree函數。我看了看它是否會替換現有的文件,以及我能夠告訴它會覆蓋現有文件,但如果有任何目錄已經存在,則失敗。如果目錄已經存在,則由於os.mkdirs失敗。

所需的進口:

import os 
import os.path 
import shutil 

採取_mkdirhttp://code.activestate.com/recipes/82465-a-friendly-mkdir/(一個評論者那邊提到os.mkdirs具有許多相同的行爲,但不會注意到_mkdir沒有失敗,如果任何一個目錄來進行已經存在)

def _mkdir(newdir): 
    """works the way a good mkdir should :) 
     - already exists, silently complete 
     - regular file in the way, raise an exception 
     - parent directory(ies) does not exist, make them as well 
    """ 
    if os.path.isdir(newdir): 
     pass 
    elif os.path.isfile(newdir): 
     raise OSError("a file with the same name as the desired " \ 
         "dir, '%s', already exists." % newdir) 
    else: 
     head, tail = os.path.split(newdir) 
     if head and not os.path.isdir(head): 
      _mkdir(head) 
     #print "_mkdir %s" % repr(newdir) 
     if tail: 
      os.mkdir(newdir) 

雖然它並不需要一個mode說法像os.mkdirscopytree不使用塔因此它不是必需的。

,然後更改copytree調用_mkdir而不是os.mkdirs

def copytree(src, dst, symlinks=False): 
    """Recursively copy a directory tree using copy2(). 

    The destination directory must not already exist. 
    If exception(s) occur, an Error is raised with a list of reasons. 

    If the optional symlinks flag is true, symbolic links in the 
    source tree result in symbolic links in the destination tree; if 
    it is false, the contents of the files pointed to by symbolic 
    links are copied. 

    XXX Consider this example code rather than the ultimate tool. 

    """ 
    names = os.listdir(src) 
    # os.makedirs(dst) 
    _mkdir(dst) # XXX 
    errors = [] 
    for name in names: 
     srcname = os.path.join(src, name) 
     dstname = os.path.join(dst, name) 
     try: 
      if symlinks and os.path.islink(srcname): 
       linkto = os.readlink(srcname) 
       os.symlink(linkto, dstname) 
      elif os.path.isdir(srcname): 
       copytree(srcname, dstname, symlinks) 
      else: 
       shutil.copy2(srcname, dstname) 
      # XXX What about devices, sockets etc.? 
     except (IOError, os.error), why: 
      errors.append((srcname, dstname, str(why))) 
     # catch the Error from the recursive copytree so that we can 
     # continue with other files 
     except Error, err: 
      errors.extend(err.args[0]) 
    try: 
     shutil.copystat(src, dst) 
    except WindowsError: 
     # can't copy file access times on Windows 
     pass 
1

只需通過將忽略參數和添加shutil(對於copytree)的 '錯誤' 類擴展丹的回答是:

def copytree(src, dst, symlinks=False, ignore=None): 
    """Recursively copy a directory tree using copy2(). 

    The destination directory must not already exist. 
    If exception(s) occur, an Error is raised with a list of reasons. 

    If the optional symlinks flag is true, symbolic links in the 
    source tree result in symbolic links in the destination tree; if 
    it is false, the contents of the files pointed to by symbolic 
    links are copied. 

    XXX Consider this example code rather than the ultimate tool. 

    """ 
    names = os.listdir(src) 
    if ignore is not None: 
     ignored_names = ignore(src, names) 
    else: 
     ignored_names = set() 

    _mkdir(dst) # XXX 
    errors = [] 
    for name in names: 
     if name in ignored_names: 
      continue 
     srcname = os.path.join(src, name) 
     dstname = os.path.join(dst, name) 
     try: 
      if symlinks and os.path.islink(srcname): 
       linkto = os.readlink(srcname) 
       os.symlink(linkto, dstname) 
      elif os.path.isdir(srcname): 
       copytree(srcname, dstname, symlinks, ignore) 
      else: 
       shutil.copy2(srcname, dstname) 
      # XXX What about devices, sockets etc.? 
     except (IOError, os.error), why: 
      errors.append((srcname, dstname, str(why))) 
     # catch the Error from the recursive copytree so that we can 
     # continue with other files 
     except shutil.Error, err: 
      errors.extend(err.args[0]) 
    try: 
     shutil.copystat(src, dst) 
    except WindowsError: 
     # can't copy file access times on Windows 
     pass 
0

這是一個有兩個distutils和shutil wokaround:

ignorePatterns=('.git') 
shutil.copytree(src, "__TMP__", ignore=shutil.ignore_patterns(ignorePatterns)) 
distutils.dir_util.copy_tree("__TMP__", dest) 
distutils.dir_util.remove_tree("__TMP__") 

注意:這不是一種有效的方法,因爲它複製兩次相同的文件。