我怎样才能提高性能?(Python存档递归提取)

2024-10-02 12:33:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试开发一个递归提取器。问题是,它递归的次数太多(每次它找到一个归档类型)并使性能受到影响。在

那么我该如何改进下面的代码呢?在

我的想法:

先获取direcories的“Dict”和file类型。文件类型钥匙组件。提取文件类型。当找到一个档案时,只提取那一个。然后重新生成Archive Dict。在

我的想法2:

在手术室步行返回生成器。我能用发电机做些什么吗?我不熟悉发电机。在

以下是当前代码:

import os, magic
m = magic.open( magic.MAGIC_NONE )
m.load()

archive_type = [ 'gzip compressed data',
        '7-zip archive data',
        'Zip archive data',
        'bzip2 compressed data',
        'tar archive',
        'POSIX tar archive',
        'POSIX tar archive (GNU)',
        'RAR archive data',
        'Microsoft Outlook email folder (>=2003)',
        'Microsoft Outlook email folder']

def extractRecursive( path ,archives):
    i=0
    for dirpath, dirnames, filenames in os.walk( path ):
        for f in filenames:
            fp = os.path.join( dirpath, f )
            i+=1
            print i
            file_type = m.file( fp ).split( "," )[0]
            if file_type in archives:
                arcExtract(fp,file_type,path,True)
                extractRecursive(path,archives)
    return "Done"



def arcExtract(file_path,file_type,extracted_path="/home/v3ss/Downloads/extracted",unlink=False):
    import subprocess,shlex


    if file_type in pst_types:
        cmd = "readpst -o  '%s' -S '%s'" % (extracted_path,file_path)
    else:
        cmd = "7z -y -r -o%s x '%s'" % (extracted_path,file_path)

    print cmd
    args= shlex.split(cmd)
    print args

    try:
        sp = subprocess.Popen( args, shell = False, stdout = subprocess.PIPE, stderr = subprocess.PIPE )
        out, err = sp.communicate()
        print out, err
        ret = sp.returncode
    except OSError:
        print "Error no %s  Message %s" % (OSError.errno,OSError.message)
        pass

    if ret == 0:
        if unlink==True:
            os.unlink(file_path)
        return "OK!"
    else:
        return "Failed"
if __name__ == '__main__':
    extractRecursive( 'Path/To/Archives' ,archive_type)

Tags: pathincmddataifostypemagic
2条回答

您可以简化您的extractRecursive方法,以使用它应该使用的os.walkos.walk已读取所有子目录,因此不需要递归。

只需删除递归调用,它就可以工作了:)

def extractRecursive(path, archives, extracted_archives=None):
    i = 0
    if not extracted_archives:
        extracted_archives = set()

    for dirpath, dirnames, filenames in os.walk(path):
        for f in filenames:
            fp = os.path.join(dirpath, f)
            i += 1
            print i
            file_type = m.file(fp).split(',')[0]
            if file_type in archives and fp not in extracted_archives:
                extracted_archives.add(fp)
                extracted_in.add(dirpath)
                arcExtract(fp, file_type, path, True)

    for path in extracted_in:
        extractRecursive(path, archives, extracted_archives)

    return "Done"

如果您想将归档文件提取到它们所在的路径之上,os.walk本身(在其正常的自顶向下操作中)无法帮助您(因为当您将一个归档文件提取到某个目录x中时,手术室步行可能,但不一定,已经考虑过x目录所以只有手术室步行一遍又一遍地看整条路你能得到所有的内容吗)。但是,我很惊讶你的代码会终止,因为存档类型的文件应该不断被发现和提取,我看不出有什么可以终止递归。(为了解决这个问题,只需保留一组已经提取的归档类型文件的所有路径,以避免再次遇到它们时再考虑它们)。

无论如何,到目前为止,最好的架构应该是,如果arcExtract返回它提取的所有文件的列表(特别是它们的目标路径),那么您可以在os.walk循环期间继续扩展一个包含所有这些提取文件的列表(无递归),然后继续在列表上循环(不需要一直询问操作系统有关文件和目录的信息,这也节省了大量的操作时间),并生成一个新的类似列表。没有递归,没有冗余的工作。我设想readpst7z能够以某种文本形式提供这样的列表(可能在它们的标准输出或错误中,您当前只是显示但不处理这些列表),您可以将其解析为一个列表。。。?

相关问题 更多 >

    热门问题