121

I'm trying to open a file, and if the file doesn't exist, I need to create it and open it for writing:

#open file for reading fn = input("Enter file to open: ") fh = open(fn,'r') # if file does not exist, create it if (!fh) fh = open ( fh, "w") 

The error message says there's an issue on the line if(!fh). Can I use exist like in Perl?

1

9 Answers 9

106

For Linux users.

If you don't need atomicity you can use os module:

import os if not os.path.exists('/tmp/test'): os.mknod('/tmp/test') 

macOS and Windows users.

On macOS for using os.mknod() you need root permissions. On Windows there is no os.mknod() method.

So as an alternative, you may use open() instead of os.mknod()

import os if not os.path.exists('/tmp/test'): with open('/tmp/test', 'w'): pass 
Sign up to request clarification or add additional context in comments.

7 Comments

macOS requires sudo privileges to run mknod so this is unlikely to be portable to Mac unless you're running your python script with sudo.
This creates a race condition between exists() and open().
How does it create a race condition? exists() is tested before open() is executed.
Because exists() and open() is two separated calls this solution is not atomic. In theory there is a time between this two function calls when another program may also check existance of a file and create it if no file found.
It does not work on Windows, os has no attribute mknod.
|
74

You can achieve the desired behaviour with

file_name = 'my_file.txt' f = open(file_name, 'a+') # open file in append mode f.write('python rules') f.close() 

These are some valid options for the second parameter mode in open():

""" w write mode r read mode a append mode w+ create file if it doesn't exist and open it in (over)write mode [it overwrites the file if it already exists] r+ open an existing file in read+write mode a+ create file if it doesn't exist and open it in append mode """ 

3 Comments

r+ does not create any file. As also mentioned here and here(in the description) r+ is for opening a file in reading and writing mode. Correct it as it might confuse people :)
w+ also clears the content of the file. Here's a complete (longer) description of each mode.
It does not work on Windows: Exception has occurred: FileNotFoundError
41

Well, first of all, in Python there is no ! operator, that'd be not. But open would not fail silently either - it would throw an exception. And the blocks need to be indented properly - Python uses whitespace to indicate block containment.

Thus we get:

fn = input('Enter file name: ') try: file = open(fn, 'r') except IOError: file = open(fn, 'w') 

1 Comment

I have been trying to figure out why this is preferable to open(fn, 'a').close(). Is it because the implicit seek in append may be too expensive?
36

Here's a quick two-liner that I use to quickly create a file if it doesn't exists.

if not os.path.exists(filename): open(filename, 'w').close() 

3 Comments

Short and concise. Please remove double quotes around "filename".
Seems like if the file path doesn't exist you could also open it in 'x' mode since you've already established that the file doesn't exist.
Needless to say that import os must be declared before using this two-liner.
15

Using input() implies Python 3, recent Python 3 versions have made the IOError exception deprecated (it is now an alias for OSError). So assuming you are using Python 3.3 or later:

fn = input('Enter file name: ') try: file = open(fn, 'r') except FileNotFoundError: file = open(fn, 'w') 

Comments

9

I think this should work:

#open file for reading fn = input("Enter file to open: ") try: fh = open(fn,'r') except: # if file does not exist, create it fh = open(fn,'w') 

Also, you incorrectly wrote fh = open(fh, "w") when the file you wanted open was fn

1 Comment

You are assuming that the file cannot be opened because it does not exist. It could be that you don't have read permissions, or the filename is invalid in some way. Bare except is not a good idea.
7

Be warned, each time the file is opened with this method the old data in the file is destroyed regardless of 'w+' or just 'w'.

with open("file.txt", 'w+') as f: f.write("file is opened for business") 

3 Comments

There's a typo in the code. It should be with open('file.txt', 'w+') as f:.
@Flux fixed typo
The answer with with to write to a new file should be placed more on top. I would use the a+ for append to the file to avoid overwrite.
2

If you know the folder location and the filename is the only unknown thing,

open(f"{path_to_the_file}/{file_name}", "w+") 

if the folder location is also unknown

try using

pathlib.Path.mkdir 

Comments

0

First let me mention that you probably don't want to create a file object that eventually can be opened for reading OR writing, depending on a non-reproducible condition. You need to know which methods can be used, reading or writing, which depends on what you want to do with the file object.

That said, you can do it as @That One Random Scrub proposed, using try: ... except:. Actually that is the proposed way, according to the python motto "It's easier to ask for forgiveness than permission".

But you can also easily test for existence:

import os # open file for reading fn = input("Enter file to open: ") if os.path.exists(fn): fh = open(fn, "r") else: fh = open(fn, "w") 

2 Comments

The comments regarding input() and raw_input() only apply to Python 2. Python 3 has replaced raw_input() with input() and the "old" use of input() is gone.
That's possible and would be/is a good improvement to make it more intuitive.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.