2017-06-18 65 views
2

我想根据我在本网站上无耻地找到的一些Python代码,在一个目录中找到最新文件的日期。函数在空序列上失败

def newest_file_in_tree(rootfnewer, extension=".avi"): 
    return max(
     (os.path.join(dirname, filename) 
     for dirname, dirnames, filenames in os.walk(rootfnewer) 
     for filename in filenames 
     if filename.endswith(extension)), 
     key=lambda fn: os.stat(fn).st_mtime) 

这可以工作,但在空目录上失败。

key=lambda fn: os.stat(fn).st_mtime) 
ValueError: max() arg is an empty sequence 

我承认我是一名Python初学者,最后一行是超出我的薪酬等级的。

任何人都可以建议我如何捕获错误并防止崩溃的功能?

回答

4

可以分离出那个无情无义Python的一个衬垫分成两个独立的线路,以确保max被称为只有当你有从中挑选文件的非空列表,最新的版本:

def newest_file_in_tree(rootfnewer, extension=".avi"): 
    files = [os.path.join(dirname, filename) 
     for dirname, dirnames, filenames in os.walk(rootfnewer) 
     for filename in filenames 
     if filename.endswith(extension)] 

    if files: 
     return max(files, key=lambda fn: os.stat(fn).st_mtime) 

    return None 

不像@ hiroprotagonist的解决方案那么漂亮,但更具可读性。

+0

@TimPietzcker YESSS!测试空列表的真实性。更新,谢谢。 –

+1

我喜欢这个,因为它可以使代码更加清晰,并且清楚地了解发生了什么。 –

+0

@TimPietzcker同意。一个更好的(尽管不太pythonic)解决方案将从该理解中去除嵌套循环! –

7

maxdefault关键字:如果可迭代为空

m = max([], key=lambda x: abs(x), default='emtpy...') 
print(m) # 'emtpy...' 

default将被退回。如果没有default这会引起ValueError


,你去会为了使用glob列出文件以不同的方式:

import os 
from glob import glob 

def newest_file_in_tree(rootdir, ext='.avi'): 
    glob_wildcard = os.path.join(rootdir, '**/*{}'.format(ext)) 
    glob_gen = glob(glob_wildcard, recursive=True) 
    return max(glob_gen, key=lambda fn: os.stat(fn).st_mtime, default='?') 

甚至更​​简洁与pathlib

from pathlib import Path 

def newest_file_in_tree(rootpath, ext='.avi'): 
    return max(Path(rootpath).glob('**/*{}'.format(ext)), 
       key=lambda pth: pth.stat().st_mtime, default='?') 
+0

很酷。不知道这一点。 –

+0

谢谢,我测试了这个,它工作正常,但我通常使用Python 2(默认情况下,它没有带有Python3!),它没有缺省值(在'Learning Python'中也没有提到) – Milliways

+0

@Milliways:你是对的,这是python 3中的新功能。没有考虑到... –