我有这个功能试图打印额外的'。'每隔一秒,它会将一个大文件夹(~3GB)从一个地方复制到另一个地方:
def copy_folder(source, destination):
print 'copying',
while shutil.copytree(src=source, dst=destination):
print '.',
time.sleep(1)
但是当我调用该函数时:
source = 'source_folder'
destination = 'destination_folder'
copy_folder(source=source, destination=destination)
它可以完全复制整个文件夹,但它不会打印出来。'。'一点都不。
我需要使用线程吗?
答案 0 :(得分:4)
Python中的线程非常简单:
import sys, shutil, time, threading
class CopyThread(threading.Thread):
def __init__(self, source, destination):
super(CopyThread, self).__init__()
self.source = source
self.destination = destination
def run(self):
time.sleep(5) # Delete me later on, I'm just here to slow things down
return shutil.copytree(src=self.source, dst=self.destination)
if __name__ == '__main__':
thread = CopyThread('source_folder', 'destination_folder')
thread.start()
while thread.is_alive():
sys.stdout.write('.')
sys.stdout.flush()
time.sleep(1)
thread.join()
只是继承threading.Thread
并覆盖run()
。之后,在该类的实例上调用.start()
,你就有了一个帖子。
答案 1 :(得分:1)
copytree将复制整个树,因此while循环将不会运行,直到复制完成并且可以评估返回值。
我的python很生疏,但我会想一下如何实现该线程(受到找到的代码here的启发)。
def copy_folder(source, destination):
self.iscopying = True
self.thread = threading.Thread(name="GPS Data", target=self.thread_run)
self.thread.setDaemon(True)
self.thread.start()
shutil.copytree(src=source, dst=destination)
self.iscopying = false
def thread_run(self):
while self.iscopying:
print '.'
time.sleep(1)
基本上,创建一个标志,告诉线程何时进行复制,然后在复制完成时将其设置为false。
答案 2 :(得分:1)
查看copytree source code,它的核心就是这个循环:
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:
# Will raise a SpecialFileError for unsupported file types
copy2(srcname, dstname)
# catch the Error from the recursive copytree so that we can
# continue with other files
except Error, err:
errors.extend(err.args[0])
except EnvironmentError, why:
errors.append((srcname, dstname, str(why)))
如果您在最后添加yield
权限,您的循环将会起作用 - 但是您将在复制的每个文件或目录之后打印,而不是按时间间隔打印(复制之间会发生time.sleep
,只需要让整个事情花费更长的时间;对于每个时间间隔,是的,你将需要线程)。但是,如果您愿意,这也可以让您提供更详细的反馈 - 例如,您可以yield name
(或yield (srcname, destname)
)能够打印上的反馈文件已被复制。
答案 3 :(得分:0)
我不知道有一个模块异步执行此操作...不是没有一个......但是你可以递归地浏览文件夹并打印“。”在每个文件/文件夹
之后