Edit: See also Dave Jones' answer: from Python 3.3, you can use the x
flag to open()
to provide this function.
Original answer below
Yes, but not using Python's standard open()
call. You'll need to use os.open()
instead, which allows you to specify flags to the underlying C code.
In particular, you want to use O_CREAT | O_EXCL
. From the man page for open(2)
under O_EXCL
on my Unix system:
Ensure that this call creates the file: if this flag is specified in conjunction with O_CREAT
, and pathname already exists, then open()
will fail. The behavior of O_EXCL
is undefined if O_CREAT
is not specified.
When these two flags are specified, symbolic links are not followed: if pathname is a symbolic link, then open()
fails regardless of where the symbolic link points to.
O_EXCL
is only supported on NFS when using NFSv3 or later on kernel 2.6 or later. In environments where NFS O_EXCL
support is not provided, programs that rely on it for performing locking tasks will contain a race condition.
So it's not perfect, but AFAIK it's the closest you can get to avoiding this race condition.
Edit: the other rules of using os.open()
instead of open()
still apply. In particular, if you want use the returned file descriptor for reading or writing, you'll need one of the O_RDONLY
, O_WRONLY
or O_RDWR
flags as well.
All the O_*
flags are in Python's os
module, so you'll need to import os
and use os.O_CREAT
etc.
Example:
import os
import errno
flags = os.O_CREAT | os.O_EXCL | os.O_WRONLY
try:
file_handle = os.open('filename', flags)
except OSError as e:
if e.errno == errno.EEXIST: # Failed as the file already exists.
pass
else: # Something unexpected went wrong so reraise the exception.
raise
else: # No exception, so the file must have been created successfully.
with os.fdopen(file_handle, 'w') as file_obj:
# Using `os.fdopen` converts the handle to an object that acts like a
# regular Python file object, and the `with` context manager means the
# file will be automatically closed when we're done with it.
file_obj.write("Look, ma, I'm writing to a new file!")