问题描述
我制作了这个程序,它需要用户输入并将其输出到新的文本文件中。
output = input('Insert your text')
f = open("text.txt","a")
f.write(output)
此代码将接受用户输入并将其打印在新的文本文件中。但是,如果该文件已存在于路径中,则python代码将追加到该文件中。我希望代码在每次运行程序时在路径中创建一个新文件。因此,第一次运行代码时,它将显示为text.txt,而第二次运行时,它将输出一个名为text(1).txt的新文件,依此类推。
解决方法
检查文件是否已经存在
import os.path
os.path.exists('filename-here.txt')
如果文件存在,则使用另一个文件名创建文件(例如-在文件名后附加日期和时间或任何数字等)
,首先检查是否存在test.txt
。如果是,则循环检查test(n).txt
,其中n
是一个从1开始的正整数。
from os.path import isfile
output = input('Insert your text')
newFileName = "text.txt"
i = 1
while isfile(newFileName):
newFileName = "text({}).txt".format(i)
i += 1
f = open(newFileName,"w")
f.write(output)
f.close()
最终,循环将到达某些n
,而文件名test(n).txt
不存在,并且将使用该名称保存文件。
检查您要创建的文件是否已经存在。如果是,则更改文件名,否则将文本写入文件。
import os
output = input('Insert your text ')
filename = 'text.txt'
i = 1
while os.path.exists(filename):
filename = 'text ('+str(i)+').txt'
i += 1
f = open(filename,"a")
f.write(output)
,
检查是否存在的问题是,如果两个进程尝试创建相同的文件,则可能存在竞争条件:
- 过程1:文件是否存在? (否)
- 过程2:文件是否存在? (否)
- 过程2:创建要写入的文件(“ w”,如果存在则将其截断)
- 过程2:写入文件。
- 过程2:关闭文件。
- 过程1:创建用于写入的相同文件(“ w”,这会截断过程2的文件)。
一种解决方法是模式'x'
(打开以进行独占创建,如果文件已经存在则失败),但是在上述情况下,这只会使进程1出错而不是截断进程2的文件。 / p>
要按照OP所述打开文件名递增的文件,可以使用以下方法:
import os
def unique_open(filename):
# "name" contains everything up to the extension.
# "ext" contains the last dot(.) and extension,if any
name,ext = os.path.splitext(filename)
n = 0
while True:
try:
return open(filename,'x')
except FileExistsError:
n += 1
# build new filename with incrementing number
filename = f'{name}({n}){ext}'
file = unique_open('test.txt')
file.write('content')
file.close()
要使该功能与上下文管理器(“ with”语句)一起使用,可以使用contextlib.contextmanager
装饰该功能并自动提供文件的.close()
:
import os
import contextlib
@contextlib.contextmanager
def unique_open(filename):
n = 0
name,ext = os.path.splitext(filename)
try:
while True:
try:
file = open(filename,'x')
except FileExistsError:
n += 1
filename = f'{name}({n}){ext}'
else:
print(f'opened {filename}') # for debugging
yield file # value of with's "as".
break # open succeeded,so exit while
finally:
file.close() # cleanup when with block exits
with unique_open('test.txt') as f:
f.write('content')
演示:
C:\>test.py
opened test.txt
C:\>test
opened test(1).txt
C:\>test
opened test(2).txt