我正在寻找以下原子版:
import os
def tryMakeFile(filename):
try:
with open(filename) as _:
return False
except FileNotFoundError:
with open(filename, mode='a') as _:
return True
Run Code Online (Sandbox Code Playgroud)
(请不要在这里评论文体问题 - 我知道这个代码在很多方面都很糟糕,但它足以说明我的问题.)
换句话说,我正在寻找一种方法来检查文件是否存在,如果不存在则创建它,在Python中,以我知道发生了哪种方式.但是这样做的方式是在多个进程之间没有竞争条件(在我给出的示例代码中,两个进程都可以认为他们创建了文件,如果第二个进程运行,而第一个进程在第一个和第二个进程之间暂停调用).
或者,换句话说,我正在寻找与Java的Files.createFile调用相当的Python .
编辑:请注意,当我说"Python"时,我的意思是"便携式Python".说"使用这个库*(*这个库只在Windows上可用,或者不在Windows上,或者仅在蓝月亮后的第二个星期二)"并不是我想要的.我正在寻找明确原子的东西,标准库和/或内置的一部分,并且它可以在通用平台上使用.
Pad*_*ham 12
您可以将os.open与os.O_CREAT | os.O_EXCL 标志一起使用,如果文件存在则会失败,它们是根据Unix和Windows上可用的文档但是我不确定Windows上是否存在原子文件创建:
os.open("filename", os.O_CREAT | os.O_EXCL)
Run Code Online (Sandbox Code Playgroud)
从linux 打开手册页:
O_EXCL如果设置了O_CREAT和O_EXCL,如果文件存在,open()将失败.检查文件是否存在以及文件的创建(如果不存在)对于执行open()的其他线程来说应该是原子的,在设置了O_EXCL和O_CREAT的同一目录中命名相同的文件名.如果设置了O_EXCL和O_CREAT,并且路径名称为符号链接,则open()将失败并将errno设置为[EEXIST],而不管符号链接的内容如何.如果设置了O_EXCL且未设置O_CREAT,则结果未定义.
如果文件存在,则不确定要执行的操作,但只需要FileExistsError在文件已存在时捕获:
import os
def try_make_file(filename):
try:
os.open(filename, os.O_CREAT | os.O_EXCL)
return True
except FileExistsError:
return False
Run Code Online (Sandbox Code Playgroud)
如果你有Python 3.3或更高版本,你可以使用'x'模式open():
'x'打开以进行独占创建,如果文件已存在则失败
def tryMakeFile(filename):
try:
with open(filename, "x") as _:
return False
except FileExistsError:
return True
Run Code Online (Sandbox Code Playgroud)
还有另一种变体,使用pathlib.Path:
from pathlib import Path
def try_make_file(filename):
try:
Path(filename).touch(exist_ok=False)
return True
except FileExistsError:
return False
Run Code Online (Sandbox Code Playgroud)
它没有明确记录,但在源代码中我们可以看到这暗示了该os.O_EXCL标志:
if not exist_ok:
flags |= os.O_EXCL
Run Code Online (Sandbox Code Playgroud)
因此,它具有与其他解决方案相同的属性(即尚不清楚这是否适用于 Windows)。