Python: Как да създам последователни имена на файлове?

Искам програмата ми да може да записва файлове в последователен формат, т.е.: file1.txt, file2.txt, file3.txt. Предназначено е само за запис на един файл при изпълнение на кода. Той не може да презапише никакви съществуващи файлове и ТРЯБВА да бъде създаден. Смаян съм.


person Mister X    schedule 08.03.2010    source източник
comment
Дубликат: stackoverflow.com/questions /2401235/. Моля, редактирайте въпросите си, не просто публикувайте същия въпрос отново.   -  person S.Lott    schedule 08.03.2010
comment
Не беше същото, питах как да внедря брояча, не бях сигурен как да го направя. Съжалявам за евентуалното объркване, просто си помислих, че ще е добре да го попитам отделно, така че всеки, който трябва да знае това, вместо това може да го намери чрез търсене.   -  person Mister X    schedule 09.03.2010
comment
Класическото решение за това е използването на флагове O_CREAT | O_EXCEL за създаване на файл, докато се използва системното повикване open. Написах пакет, който използва това и улеснява създаването на такива файлове: pypi.python.org/pypi/seqfile   -  person musically_ut    schedule 27.04.2015


Отговори (3)


Два избора:

  1. Файл за брояч.

  2. Проверете директорията.

Файл с брояч.

with open("thecounter.data","r") as counter:
    count= int( counter.read() )

count += 1

Всеки път, когато създавате нов файл, вие също пренаписвате файла с брояча със съответния номер. Много, много бързо. Теоретично обаче е възможно двете да се разпаднат. в случай на катастрофа.

Можете също така да направите файла с брояча малко по-умен, като го направите малко парче код на Python.

settings= {}
execfile( "thecounter.py", settings )
count = settings['count']

След това, когато актуализирате файла, пишете малко парче код на Python: count = someNumber. Можете да добавяте коментари и други маркери към този файл, за да опростите счетоводството си.

Проверете директорията.

import os
def numbers( path ):
    for filename in os.listdir(path):
        name, _ = os.path.splitext()
        yield int(name[4:])
count = max( numbers( '/path/to/files' ) )

count += 1

По-бавно. Никога не е имало проблем със синхронизацията.

person S.Lott    schedule 08.03.2010
comment
stackoverflow.com/questions/2401235 / - person badp; 08.03.2010

Или можете да добавите текущото системно време, за да направите уникални имена на файлове...

person ultrajohn    schedule 08.03.2010

Ето начина, по който внедрих това:

import os
import glob
import re

#we need natural sort to avoid having the list sorted as such:
#['./folder1.txt', './folder10.txt', './folder2.txt', './folder9.txt']
def sorted_nicely(strings):
    "Sort strings the way humans are said to expect."
    return sorted(strings, key=natural_sort_key)

def natural_sort_key(key):
    import re
    return [int(t) if t.isdigit() else t for t in re.split(r'(\d+)', key)]

#check if folder.txt exists
filename = "folder.txt" #default file name

#if it does find the last count
if(os.path.exists(filename)):
        result = sorted_nicely( glob.glob("./folder[0-9]*.txt"))
        if(len(result)==0):
                filename="folder1.txt"
        else:
                last_result = result[-1]
                number = re.search( "folder([0-9]*).txt",last_result).group(1)
                filename="folder%i.txt"%+(int(number)+1)

Благодаря на Дариус Бейкън за функциите за естествено сортиране (вижте неговия отговор тук: https://stackoverflow.com/a/341730)

Съжаляваме, ако горният код е объркващ

person Nuno Furtado    schedule 27.03.2014
comment
Предложение: за да избегнете проблеми с TOCTTOU, направете цикъл, в който се опитвате да отворите файла с флаг за създаване, което трябва да предизвика изключение, ако вече съществува, което можете да хванете и след това да опитате отново със следващия номер. - person Darius Bacon; 10.04.2014