2011-09-25 2 views
4

나는 shutil의 copytree 기능이 제공하는 무시 패턴을 원합니다. 그리고 src 트리가 distutil.dir_util.copy_tree와 같은 dest 디렉토리의 모든 존재하는 파일/폴더를 대체하기를 원합니다.(distutil + shutil) * copytree =?

저는 상당히 새로운 Python 사용자입니다.이 게시물을 찾을 수없는 것 같습니다.

+0

흥미 롭습니다. 그리고 당신의 질문은 무엇입니까? – knitti

+0

삶의 의미는 무엇입니까? Hehe jk. – Michael

+0

둘 다 존재하는 파일/디렉토리를 대체하고 ignore 패턴을 취할 수있는 복사 트리 기능을 사용하고 싶습니다. shutils 및 distutils 각각은 내가 원하는 기능의 절반을 가지고 있습니다. – Michael

답변

3

나는이 작은 말을하려고했으나하지 않았습니다. http://docs.python.org/library/shutil.html에는 copytree 기능의 버전이 있습니다. 필자는 기존 파일을 대체 할 것인지, 기존 파일을 덮어 쓰겠다고 말할 수 있는지 알아보기 위해 디렉터리를 살펴 보았지만 이미 존재하는 디렉터리가있는 경우 실패합니다. 디렉토리가 이미 존재하면 os.mkdirs으로 인해 실패합니다.

필요한 수입 :

import os 
import os.path 
import shutil 

http://code.activestate.com/recipes/82465-a-friendly-mkdir/에서 _mkdir 복용의 (a 주석이 os.mkdirs이 같은 동작의 대부분이 있음을 언급하지만 _mkdir가 디렉토리의 경우 하나를 실패하지 않는 것을 통지하지 않는 이상 이 os.mkdirs 같은 mode 인수를하지 않지만 그쪽을 사용하지 않습니다)

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) 

copytree을 이미 만든 존재한다 그래서 필요하지 않습니다.

그리고 _mkdir 대신 os.mkdirs 전화를 copytree을 변경

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

그냥이 인수를 무시 통합 및 (copytree 용) '오류'클래스에 또 shutil을 추가하여 댄의 답변을 확장 :

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__") 

참고 : 동일한 파일을 두 번 복사하기 때문에 효율적인 방법은 아닙니다.

관련 문제