Python Windows File Copy с поддержкой подстановочных знаков

Я делал это все время:

result = subprocess.call(['copy', '123*.xml', 'out_folder.', '/y'])
if result == 0: 
    do_something()
else:
    do_something_else()

до сегодняшнего дня я начал смотреть в модули pywin32, затем я увидел такие функции, как win32file.CopyFiles (), но затем я обнаружил, что он может не поддерживать копирование файлов в каталог. Возможно, эта функциональность где-то спрятана, но я ее еще не нашел.

Я также пробовал комбинацию" glob "и" shutil", но" glob " невероятно медленный, если есть много файлов.

Итак, как вы эмулируете эту Windows команда с Python?

copy 123*.xml out_folder. /y

5 ответов


следующий код предоставляет портативную реализацию.

обратите внимание, что я использую iglob (добавлено в Python 2.5), который создает генератор, поэтому он сначала не загружает весь список файлов в память (что и делает glob).

from glob import iglob
from shutil import copy
from os.path import join

def copy_files(src_glob, dst_folder):
    for fname in iglob(src_glob):
        copy(fname, join(dst_folder, fname))

if __name__=='__main__':
    copy_files("123*.xml", "out_folder")

дополнительные документы:


приведенный ниже пример довольно наивен - не делает никакой проверки, если что-то пойдет не так, и не создает никаких каталогов, но может делать то, что вы хотите:

import glob
import shutil

for path in glob.iglob('123*.xml'):
    shutil.copy(path, 'out_folder/%s' % path)

см. также:http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html

использование win32file / shfileoperation copy кажется более функциональным, но не таким портативным и более сложным в использовании.


посмотреть Глоб и shutil прежде чем двигаться дальше.

разветвление подпроцесса для копирования файла относительно неэффективно. Используя shutil будет более эффективным.


"glob" невероятно медленный, если есть много файлов.

glob медленный, есть много результатов, потому что он возвращает один огромный список всех результатов в подходе "Большого взрыва". Если есть много результатов, это будет использовать много памяти и занимает много времени.

вместо этого используйте iglob, как предложено предыдущим плакатом. iglob создает и возвращает один объект итератора, который может использоваться для перебора результатов, не имея их всех в памяти одновременно. Гораздо эффективнее, если есть много совпадений.

В общем, всякий раз, когда вы пишете код, например "для x в [glob.шарик. ..] "вы должны использовать glob.вместо iglob.


import os
import shutil
path=os.path.join("/home","mypath")
destination=os.path.join("/destination","dir")
for r,d,f in os.walk(path):
     for files in f:
           if files.endswith(".xml"):
                 try:
                     shutil.copy(os.path.join(r,files) , destination)
                 except IOError,e:
                     print e