Vilket är det mest eleganta sättet att kontrollera om katalogen som en fil ska skrivas till existerar, och om inte, skapa katalogen med hjälp av Python? Här är vad jag försökte:
import os
file_path = "/my/directory/filename.txt"
directory = os.path.dirname(file_path)
try:
os.stat(directory)
except:
os.mkdir(directory)
f = file(filename)
På något sätt missade jag os.path.exists
(tack kanja, Blair och Douglas). Detta är vad jag har nu:
def ensure_dir(file_path):
directory = os.path.dirname(file_path)
if not os.path.exists(directory):
os.makedirs(directory)
Finns det en flagga för "open" som gör att detta sker automatiskt?
Jag ser två svar med goda egenskaper, men båda har en liten brist, så jag ska ge min syn på det:
Prova os.path.exists
, och överväg os.makedirs
för skapandet.
import os
if not os.path.exists(directory):
os.makedirs(directory)
Som noterats i kommentarer och på andra ställen finns det ett kapplöpningsvillkor – om katalogen skapas mellan anropet os.path.exists
och os.makedirs
, kommer os.makedirs
att misslyckas med ett OSError
. Tyvärr är det inte helt säkert att fånga upp OSError
och fortsätta, eftersom det kommer att ignorera ett misslyckande med att skapa katalogen på grund av andra faktorer, t.ex. otillräckliga behörigheter, full disk, etc.
Ett alternativ skulle vara att fånga upp OSError
och undersöka den inbäddade felkoden (se 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
Alternativt skulle det kunna finnas en andra os.path.exists
, men anta att en annan skapade katalogen efter den första kontrollen och sedan tog bort den före den andra – vi kan fortfarande bli lurade.
Beroende på applikationen kan faran med samtidiga operationer vara större eller mindre än faran med andra faktorer, t.ex. filbehörigheter. Utvecklaren måste veta mer om den specifika tillämpning som utvecklas och dess förväntade miljö innan han eller hon väljer ett genomförande.
Moderna versioner av Python förbättrar den här koden en hel del, både genom att exponera FileExistsError
(i 3.3+)...
try:
os.makedirs("path/to/directory")
except FileExistsError:
# directory already exists
pass
...och genom att tillåta ett nyckelordsargument till os.makedirs
som heter exist_ok
(i 3.2+).
os.makedirs("path/to/directory", exist_ok=True) # succeeds even if directory exists.
Kontrollera os.makedirs
: (Kontrollerar att hela sökvägen finns.)
För att hantera det faktum att katalogen kan finnas, fånga upp OSError
.
(Om exist_ok
är False
(standard), så uppstår ett OSError
om målkatalogen redan existerar.)
import os
try:
os.makedirs('./path/to/somewhere')
except OSError:
pass
Prova funktionen os.path.exists
.
if not os.path.exists(dir):
os.mkdir(dir)