Wat is de meest elegante manier om te controleren of de directory waar een bestand naar toe geschreven moet worden bestaat, en zo niet, de directory aan te maken met Python? Dit is wat ik geprobeerd heb:
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)
Op de een of andere manier miste ik os.path.exists
(bedankt kanja, Blair, en Douglas). Dit is wat ik nu heb:
def ensure_dir(file_path):
directory = os.path.dirname(file_path)
if not os.path.exists(directory):
os.makedirs(directory)
Is er een vlag voor "open", die dit automatisch laat gebeuren?
Ik zie twee antwoorden met goede kwaliteiten, elk met een klein minpuntje, dus ik zal er mijn mening over geven:
Probeer os.path.exists
, en overweeg os.makedirs
voor de creatie.
import os
if not os.path.exists(directory):
os.makedirs(directory)
Zoals opgemerkt in commentaren en elders, is er een race conditie – als de directory wordt aangemaakt tussen de os.path.exists
en de os.makedirs
calls, zal de os.makedirs
falen met een OSError
. Helaas is het niet waterdicht om de OSError
af te vangen en verder te gaan, omdat het falen om de map aan te maken door andere factoren, zoals onvoldoende rechten, volle schijf, enz. wordt genegeerd.
Een optie zou zijn om de OSError
te vangen en de ingesloten foutcode te onderzoeken (zie 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
Als alternatief zou er een tweede os.path.exists
kunnen zijn, maar stel dat een ander de directory na de eerste controle heeft aangemaakt, en hem vervolgens voor de tweede heeft verwijderd – we zouden nog steeds voor de gek gehouden kunnen worden.
Afhankelijk van de toepassing, kan het gevaar van gelijktijdige bewerkingen meer of minder zijn dan het gevaar van andere factoren zoals bestandspermissies. De ontwikkelaar zou meer moeten weten over de specifieke toepassing die wordt ontwikkeld en de verwachte omgeving voordat hij een implementatie kiest.
Moderne versies van Python verbeteren deze code behoorlijk, zowel door het blootleggen van FileExistsError
(in 3.3+)...
try:
os.makedirs("path/to/directory")
except FileExistsError:
# directory already exists
pass
...en door een sleutelwoord argument aan os.makedirs
genaamd exist_ok
toe te staan (in 3.2+).
os.makedirs("path/to/directory", exist_ok=True) # succeeds even if directory exists.
Controleer os.makedirs
: (Het zorgt ervoor dat het volledige pad bestaat.)
Om om te gaan met het feit dat de directory misschien bestaat, vang OSError
.
(Als exist_ok
False
is (de standaard), wordt een OSError
opgewekt als de doelmap al bestaat).
import os
try:
os.makedirs('./path/to/somewhere')
except OSError:
pass
Probeer de os.path.exists
functie
if not os.path.exists(dir):
os.mkdir(dir)