OS.Walk()两次访问同一文件夹



我正在使用诱变库编写简单的脚本,该库计算文件夹中的音频文件和文件夹的整个音频播放时间(包括来自子文件夹的音频文件)。

import os,sys
from datetime import datetime,timedelta
from mutagen.mp3 import MP3
from mutagen.flac import FLAC
from mutagen.aac import AAC
from mutagen.aiff import AIFF
from mutagen.asf import ASF
audio_ext={"mp3":lambda x: MP3(x).info.length,
           "aac":lambda x: AAC(x).info.length,
           "wmv":lambda x: ASF(x).info.length,
           "wma":lambda x: ASF(x).info.length,
           "asf":lambda x: ASF(x).info.length,
           "flac":lambda x: FLAC(x).info.length,
           "aiff":lambda x: AIFF(x).info.length,}
def scan_lib(path):
    playtime = 0
    audio_files = 0
    for root,dirs,files in os.walk(path,followlinks=False):
        for f in files:
           try:
               playtime += audio_ext[f[len(f)-f[::-1].index('.'):]](os.path.join(root,f))
               audio_files += 1
           except (KeyError,ValueError):
               pass
        for d in dirs:
            dir_playtime,dir_audios = scan_lib(os.path.join(root,d))
            playtime +=dir_playtime
            audio_files += dir_audios
    print("nLibrary:",path)
    print("Amount of audio files:",audio_files)
    print("Total playing time:nDaystHourstMintSecn%dt%dt%dt%dn" % convert_pt(playtime))
    return playtime,audio_files
def convert_pt(sec):
    t = datetime(1,1,1) + timedelta(seconds=int(sec))
    return t.day-1, t.hour,t.minute,t.second
main_path = sys.argv[1]
playtime,audio_files = scan_lib(main_path)

经过一些测试,我发现我的脚本两次访问了一些文件夹。通常,这些目录是另一个子文件夹中的子文件夹。结果它打印了这种结果:

$ python3 music_scan.py 
Library: ~/Music/
Amount of audio files: 3520
Total playing time:
Days    Hours   Min Sec
9   7   30  26

实际上,如果您将所有音频轨道移动到一个文件夹中并在该测试文件夹上运行脚本,则会显示不同的结果:

$ python3 music_scan.py ~/test
Library: ~/test/
Amount of audio files: 885
Total playing time:
Days    Hours   Min Sec
2   15  49  9

实际上,测试文件夹中的音轨数量为885。我用ls | wc -l命令检查了一下那么,为什么OS.Walk()访问两次子文件夹?

os.walk已经递归地走整个目录树。

但是,您递归地调用您的方法scan_lib

def scan_lib(path):
    ...
    for root,dirs,files in os.walk(path,followlinks=False):
        ...
        for d in dirs:
            dir_playtime,dir_audios = scan_lib(os.path.join(root,d))
            ...

使用os.listdir代替os.walk并保留递归电话,或者简单地删除以for d in dirs:开头的4行。

最新更新