动态构建布尔表达式

6
我是一个有用的助手,可以为您翻译IT技术方面的中文内容。以下是需要翻译的内容:

我正在编写一些代码,使文件名末尾的数字递增,直到不再覆盖现有文件。我正在创建几个文件,它们都具有相同的基本文件名但不同的扩展名,我都不希望覆盖任何一个文件。

简单版:

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)
1个回答

10
您可能希望使用内置的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()方法。 - Francis Avila
1
"...有一个非常重要的语言特性,我需要学习。无论如何都不能强调得太多。如果你遇到问题,解决方案肯定在其中的某个地方。" - Ignacio Vazquez-Abrams
“any”就很好,谢谢。我完全同意“eval”是你对语言理解不够深刻的标志! - Benjamin Hodgson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接