How do I check if directory exists in Python?
Use os.path.isdir
for directories only:
>>> import os
>>> os.path.isdir('new_folder')
True
Use os.path.exists
for both files and directories:
>>> import os
>>> os.path.exists(os.path.join(os.getcwd(), 'new_folder', 'file.txt'))
False
Alternatively, you can use pathlib
:
>>> from pathlib import Path
>>> Path('new_folder').is_dir()
True
>>> (Path.cwd() / 'new_folder' / 'file.txt').exists()
False
How can I safely create a nested directory?
On Python ≥ 3.5, use pathlib.Path.mkdir
:
from pathlib import Path
Path("/my/directory").mkdir(parents=True, exist_ok=True)
For older versions of Python, I see two answers with good qualities, each with a small flaw, so I will give my take on it:
Try os.path.exists
, and consider os.makedirs
for the creation.
import os
if not os.path.exists(directory):
os.makedirs(directory)
As noted in comments and elsewhere, there's a race condition – if the directory is created between the os.path.exists
and the os.makedirs
calls, the os.makedirs
will fail with an OSError
. Unfortunately, blanket-catching OSError
and continuing is not foolproof, as it will ignore a failure to create the directory due to other factors, such as insufficient permissions, full disk, etc.
One option would be to trap the OSError
and examine the embedded error code (see Is there a cross-platform way of getting information from Python’s OSError):
import os, errno
try:
os.makedirs(directory)
except OSError as e:
if e.errno != errno.EEXIST:
raise
Alternatively, there could be a second os.path.exists
, but suppose another created the directory after the first check, then removed it before the second one – we could still be fooled.
Depending on the application, the danger of concurrent operations may be more or less than the danger posed by other factors such as file permissions. The developer would have to know more about the particular application being developed and its expected environment before choosing an implementation.
Modern versions of Python improve this code quite a bit, both by exposing FileExistsError
(in 3.3+)...
try:
os.makedirs("path/to/directory")
except FileExistsError:
# directory already exists
pass
...and by allowing a keyword argument to os.makedirs
called exist_ok
(in 3.2+).
os.makedirs("path/to/directory", exist_ok=True) # succeeds even if directory exists.
Python: Check if a directory exists using os module
Have you read the docs for the os
module?
Check out the following two links:
os.path.exists()
Return True if path refers to an existing path.
os.path.isdir()
Return True if path is an existing directory.
How do I check if a directory exists and then, if so, ask for a new directory name in Python?
Problem
When you are calling the function recursively, you are not returning from the previously called function.
What happens is, when you call the casefile first time and enter an existing name i.e Case1
, an entry is created in the stack for it. Lets call it casefile{1}. At the line casefile()
in the else statement, the function will be called recursively.
Now, due to this recursive call, another entry for the function is created in the stack. Lets call this casefile{2}. Now the controlled would be passed to this function, but note that casefile{1} has not yet run its course - you have not returned from it.
So now the control is at casefile{2}. This time you enter a non-existing name i.e Case2
. The casefile{2} does not go to the else branch and thus no more recursive calls would be made. So not it prints the name just like you asked it to (which in the scope of casefile{2} happens to be Case2, and returns the name.
But now the control goes back to casefile{1}, which will now exit the else statement and run the next line: print case_name
, which for the scope of casefile{1} happens to be Case1. So it prints it and returns.
Solution
You should return after calling the function recursively.
Please change the code to this:
def casefile():
print '\n\nPlease enter a case name/reference: '
case_name = raw_input()
if not os.path.exists('C:\\Users\\laura17\\Documents\\ProgrammeOutput\\{}'.format(case_name)):
os.mkdir('C:\\Users\\laura17\\Documents\\ProgrammeOutput\\{}'.format(case_name))
print '\n{} case file created. All logs will be saved to C:\Users\laura17\Documents\ProgrammeOutput\{}' \
.format(case_name, case_name)
else:
print '\n**Case already exists. Please choose a different case name.**'
return casefile()
print case_name
return case_name
Please note that i have changed the line casefile()
in the else statement to return casefile()
.
This would only print/return the name being passed to it by its recursively called functions.
Hope this helps. Cheers!
Related Topics
What Is the Best (Idiomatic) Way to Check the Type of a Python Variable
How to Get Most Informative Features for Scikit-Learn Classifiers
Matplotlib Legend Markers Only Once
What Determines Which Strings Are Interned and When
Does Python Have a Stack/Heap and How Is Memory Managed
Pandas Dataframe Concat VS Append
Django Rest Framework Upload Image: "The Submitted Data Was Not a File"
Processing Single File from Multiple Processes
How to Insert Pandas Dataframe via MySQLdb into Database
Conditionally Fill Column Values Based on Another Columns Value in Pandas
MAC Os X - Environmenterror: MySQL_Config Not Found
Error Installing Geopandas:" a Gdal API Version Must Be Specified " in Anaconda