How do I create a incrementing filename in Python?

2019-01-21 20:04发布

I'm creating a program that will create a file and save it to the directory with the filename sample.xml. Once the file is saved when i try to run the program again it overwrites the old file into the new one because they do have the same file name. How do I increment the file names so that whenever I try to run the code again it will going to increment the file name. and will not overwrite the existing one. I am thinking of checking the filename first on the directory and if they are the same the code will generate a new filename:

fh = open("sample.xml", "w")
rs = [blockresult]
fh.writelines(rs)
fh.close()

9条回答
【Aperson】
2楼-- · 2019-01-21 20:31

Another example using recursion

import os
def checkFilePath(testString, extension, currentCount):
    if os.path.exists(testString + str(currentCount) +extension):
        return checkFilePath(testString, extension, currentCount+1)
    else:
        return testString + str(currentCount) +extension

Use:

checkFilePath("myfile", ".txt" , 0)
查看更多
叼着烟拽天下
3楼-- · 2019-01-21 20:33

I would iterate through sample[int].xml for example and grab the next available name that is not used by a file or directory.

import os

i = 0
while os.path.exists("sample%s.xml" % i):
    i += 1

fh = open("sample%s.xml" % i, "w")
....

That should give you sample0.xml initially, then sample1.xml, etc.

Note that the relative file notation by default relates to the file directory/folder you run the code from. Use absolute paths if necessary. Use os.getcwd() to read your current dir and os.chdir(path_to_dir) to set a new current dir.

查看更多
ゆ 、 Hurt°
4楼-- · 2019-01-21 20:34

You can use a while loop with a counter which checks if a file with a name and the counter's value exists if it does then move on else break and make a file.

I have done it in this way for one of my projects:`

from os import path
import os

i = 0
flnm = "Directory\\Filename" + str(i) + ".txt"
while path.exists(flnm) :
    flnm = "Directory\\Filename" + str(i) + ".txt"
    i += 1
f = open(flnm, "w") #do what you want to with that file...
f.write(str(var))
f.close() # make sure to close it.

`

Here the counter i starts from 0 and a while loop checks everytime if the file exists, if it does it moves on else it breaks out and creates a file from then you can customize. Also make sure to close it else it will result in the file being open which can cause problems while deleting it. I used path.exists() to check if a file exists. Don't do from os import * it can cause problem when we use open() method as there is another os.open() method too and it can give the error. TypeError: Integer expected. (got str) Else wish u a Happy New Year and to all.

查看更多
干净又极端
5楼-- · 2019-01-21 20:37

Another solution that avoids the use of while loop is to use os.listdir() function which returns a list of all the files and directories contained in a directory whose path is taken as an argument.

To answer the example in the question, supposing that the directory you are working in only contains "sample_i.xlm" files indexed starting at 0, you can easily obtain the next index for the new file with the following code.

import os

new_index = len(os.listdir('path_to_file_containing_only_sample_i_files'))
new_file = open('path_to_file_containing_only_sample_i_files/sample_%s.xml' % new_index, 'w')
查看更多
smile是对你的礼貌
6楼-- · 2019-01-21 20:39

The two ways to do it are:

  1. Check for the existence of the old file and if it exists try the next file name +1
  2. save state data somewhere

an easy way to do it off the bat would be:

import os.path as pth
filename = "myfile"
filenum = 1
while (pth.exists(pth.abspath(filename+str(filenum)+".py")):
    filenum+=1
my_next_file = open(filename+str(filenum)+".py",'w')

as a design thing, while True slows things down and isn't a great thing for code readability


edited: @EOL contributions/ thoughts

so I think not having .format is more readable at first glance - but using .format is better for generality and convention so.

import os.path as pth
filename = "myfile"
filenum = 1
while (pth.exists(pth.abspath(filename+str(filenum)+".py")):
    filenum+=1
my_next_file = open("{}{}.py".format(filename, filenum),'w')
# or 
my_next_file = open(filename + "{}.py".format(filenum),'w')

and you don't have to use abspath - you can use relative paths if you prefer, I prefer abs path sometimes because it helps to normalize the paths passed :).

import os.path as pth
filename = "myfile"
filenum = 1
while (pth.exists(filename+str(filenum)+".py"):
    filenum+=1
##removed for conciseness
查看更多
Root(大扎)
7楼-- · 2019-01-21 20:40

Without storing state data in an extra file, a quicker solution to the ones presented here would be to do the following:

from glob import glob
import os

files = glob("somedir/sample*.xml")
files = files.sorted()
cur_num = int(os.path.basename(files[-1])[6:-4])
cur_num += 1
fh = open("somedir/sample%s.xml" % cur_num, 'w')
rs = [blockresult]
fh.writelines(rs)
fh.close()

This will also keep incrementing, even if some of the lower numbered files disappear.

The other solution here that I like (pointed out by Eiyrioü) is the idea of keeping a temporary file that contains your most recent number:

temp_fh = open('somedir/curr_num.txt', 'r')
curr_num = int(temp_fh.readline().strip())
curr_num += 1
fh = open("somedir/sample%s.xml" % cur_num, 'w')
rs = [blockresult]
fh.writelines(rs)
fh.close()
查看更多
登录 后发表回答