Копирование файлов в Python для Windows с поддержкой подстановочных знаков - PullRequest
9 голосов
/ 06 апреля 2010

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

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 ]

10 голосов
/ 06 апреля 2010

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

Обратите внимание, что я использую 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")

Дополнительная документация:

7 голосов
/ 06 апреля 2010

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

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 кажется более функциональным, но не столь переносимым и более сложным в использовании.

3 голосов
/ 06 апреля 2010

Посмотрите на glob и shutil прежде чем идти дальше.

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

1 голос
/ 06 апреля 2010
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
1 голос
/ 06 апреля 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...