[英]A way to create files and directories without overwriting
You know how when you download something and the downloads folder contains a file with the same name, instead of overwriting it or throwing an error, the file ends up with a number appended to the end? 你知道当你下载的东西和下载文件夹包含一个同名的文件,而不是覆盖它或抛出错误时,文件最后会附加一个数字吗? For example, if I want to download
my_file.txt
, but it already exists in the target folder, the new file will be named my_file(2).txt
. 例如,如果我想下载
my_file.txt
,但它已经存在于目标文件夹中,则新文件将命名为my_file(2).txt
。 And if I try again, it will be my_file(3).txt
. 如果我再试一次,它将是
my_file(3).txt
。
I was wondering if there is a way in Python 3.x to check that and get a unique name (not necessarily create the file or directory). 我想知道在Python 3.x中是否有办法检查并获得一个唯一的名称(不一定是创建文件或目录)。 I'm currently implementing it doing this:
我目前正在实现它:
import os
def new_name(name, newseparator='_')
#name can be either a file or directory name
base, extension = os.path.splitext(name)
i = 2
while os.path.exists(name):
name = base + newseparator + str(i) + extension
i += 1
return name
In the example above, running new_file('my_file.txt')
would return my_file_2.txt
if my_file.txt
already exists in the cwd. 在上面的例子中,运行
new_file('my_file.txt')
将返回my_file_2.txt
如果my_file.txt
已经在CWD存在。 name
can also contain the full or relative path, it will work as well. name
也可以包含完整或相对路径,它也可以工作。
I would use PathLib and do something along these lines: 我会使用PathLib并沿着这些方向做一些事情:
from pathlib import Path
def new_fn(fn, sep='_'):
p=Path(fn)
if p.exists():
if not p.is_file():
raise TypeError
np=p.resolve(strict=True)
parent=str(np.parent)
extens=''.join(np.suffixes) # handle multiple ext such as .tar.gz
base=str(np.name).replace(extens,'')
i=2
nf=parent+base+sep+str(i)+extens
while Path(nf).exists():
i+=1
nf=parent+base+sep+str(i)+extens
return nf
else:
return p.parent.resolve(strict=True) / p
This only handles files as written but the same approach would work with directories (which you added later.) I will leave that as a project for the reader. 这只处理文件,但是相同的方法适用于目录(稍后添加)。我将把它留作读者的项目。
Another way of getting a new name would be using the built-in tempfile
module: 获取新名称的另一种方法是使用内置的
tempfile
模块:
from pathlib import Path
from tempfile import NamedTemporaryFile
def new_path(path: Path, new_separator='_'):
prefix = str(path.stem) + new_separator
dir = path.parent
suffix = ''.join(path.suffixes)
with NamedTemporaryFile(prefix=prefix, suffix=suffix, delete=False, dir=dir) as f:
return f.name
If you execute this function from within Downloads directory, you will get something like: 如果从Downloads目录中执行此功能,您将获得如下内容:
>>> new_path(Path('my_file.txt'))
'/home/krassowski/Downloads/my_file_90_lv301.txt'
where the 90_lv301
part was generated internally by the Python's tempfile
module. 90_lv301
部分是由Python的tempfile
模块在内部生成的。
Note : with the delete=False
argument, the function will create (and leave undeleted) an empty file with the new name. 注意 :使用
delete=False
参数时,该函数将使用新名称创建(并保留未删除的)空文件。 If you do not want to have an empty file created that way, just remove the delete=False
, however keeping it will prevent anyone else from creating a new file with such name before your next operation (though they could still overwrite it). 如果您不希望以这种方式创建空文件,只需删除
delete=False
,但是保留它会阻止其他人在您下一次操作之前创建具有此类名称的新文件(尽管它们仍然可以覆盖它)。
Simply put, having delete=False
prevents concurrency issues if you (or the end-user) were to run your program twice at the same time. 简单地说,如果您(或最终用户)同时运行您的程序两次,则
delete=False
阻止并发问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.