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

拡張機能が 2 つ以上ある場合、この状態は明らかに非常に長く醜いものになる可能性があります。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)
4

1 に答える 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

これにより、必要なTrueorがより単純な構文で計算されます。False

一般に、 Python のような動的言語を使用したいという誘惑に駆られた場合は、学ぶ必要のある重要な言語機能があることを意味します動的言語は、より多くのコードを書くコードを作成して維持しようとする災害なしeval()に、コードを美しくするはずです。

于 2012-09-19T15:32:07.943 に答える