2012-09-19 64 views
6

我正在编写一些代码,在文件名末尾增加数字,直到它不再覆盖现有文件。我创建了几个文件,所有文件都具有相同的基本文件名,但扩展名不同,我都不想覆盖它们。动态构建布尔表达式

天真的版本:

prefix = 'hello0' 
while os.path.exists(prefix + '.abc') or os.path.exists(prefix + '.def') or os.path.exists(prefix + '.ghi'): 
    n = int(prefix[-1]) 
    prefix = prefix[:-1] + str(n + 1) # I know this doesn't work when n reaches two digits; my full code involves a regular expression 

状况可以得到明显很长的又丑的时候有超过两扩展更多。我将它抽象为for循环。

我的版本:

prefix = 'hello0' 
extensions = ('.abc', '.def', '.ghi') # there could be even more than this 
condition = True 
while condition: 
    condition = False 
    # if any of the paths still exist, set the condition back to True 
    for extension in extensions: 
     if os.path.exists(prefix + extension): 
      condition = True 

    n = int(prefix[-1]) 
    prefix = prefix[:-1] + str(n + 1) 

我还是觉得这是一个有点笨拙:它不是完全清楚什么while回路实际测试。是否可以动态构建布尔型表达式,而不是设置布尔型

我认为以下可能的工作(我没有测试过,我只想到它在写这个!),但我不认为我应该诉诸eval

prefix = 'hello0' 
extensions = ('.abc', '.def', '.ghi') 

test = 'False' 
for extension in extensions: 
    test += " or os.path.exists(prefix + '" + extension + "')" 
while eval(test): 
    n = int(prefix[-1]) 
    prefix = prefix[:-1] + str(n + 1) 

回答

9

你可能要使用any()内置有发电机:

while any(os.path.exists(prefix + extension) for extension in extensions): 

    # then increment prefix and try again, as in your example code 

这个计算,你需要有一个简单的语法的TrueFalse

一般来说,如果我曾经感觉像Python这样的动态语言使用eval()的诱惑,那么就意味着有一个重要的语言功能,我需要了解。动态语言应该使代码变得美丽没有尝试编写和维护代码即写入多代码的灾难 - 因此,通过询问你的方法,你完成了正确的事情。

+1

它也做短路评估,就像一串'或'表达式。还有一个相应的all()方法。 –

+1

“......我需要了解一个重要的语言功能。”无法强调这一点。如果您遇到问题,该解决方案就在*某处*。 –

+0

'any'是完美的,谢谢。我完全同意'eval'是一个标志,你错过了一些关于该语言的信息! –