Koks elegantiškiausias būdas patikrinti, ar katalogas, į kurį ketinama įrašyti failą, egzistuoja, o jei ne, sukurti katalogą naudojant "Python"? Štai ką bandžiau:
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)
Kažkaip nepastebėjau os.path.exists
(ačiū kanja, Blair ir Douglas). Štai ką turiu dabar:
def ensure_dir(file_path):
directory = os.path.dirname(file_path)
if not os.path.exists(directory):
os.makedirs(directory)
Ar yra "open" vėliavėlė, kad tai įvyktų automatiškai?
Matau du atsakymus su geromis savybėmis ir po nedidelį trūkumą, todėl pateiksiu savo požiūrį:
Išbandykite os.path.exists
ir apsvarstykite os.makedirs
sukūrimui.
import os
if not os.path.exists(directory):
os.makedirs(directory)
Kaip pažymėta komentaruose ir kitur, yra lenktynių sąlyga; jei katalogas sukuriamas tarp os.path.exists
ir os.makedirs
iškvietimų, os.makedirs
nepavyks su OSError
. Deja, visuotinis OSError
fiksavimas ir tęsimas nėra patikimas, nes bus ignoruojamas nesėkmingas katalogo sukūrimas dėl kitų veiksnių, pavyzdžiui, nepakankamų leidimų, pilno disko ir t. t.
Viena iš galimybių būtų gaudyti OSError
ir nagrinėti įterptą klaidos kodą (žr. skyrių Is there 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
Arba gali būti antrasis os.path.exists
, bet tarkime, kad kitas sukūrė katalogą po pirmojo patikrinimo, o paskui jį pašalino prieš antrąjį – mes vis tiek galime būti apgauti.
Priklausomai nuo taikomosios programos, vienu metu atliekamų operacijų pavojus gali būti didesnis arba mažesnis nei pavojus, kurį kelia kiti veiksniai, pavyzdžiui, failų leidimai. Kūrėjas, prieš pasirinkdamas realizaciją, turėtų daugiau sužinoti apie konkrečią kuriamą taikomąją programą ir numatomą jos aplinką.
Šiuolaikinėse Python versijose šis kodas yra gerokai patobulintas, nes jame atsirado FileExistsError
(3.3+ versijoje)...
try:
os.makedirs("path/to/directory")
except FileExistsError:
# directory already exists
pass
...ir leidžiant raktinį os.makedirs
argumentą, vadinamą exist_ok
(3.2+ versijoje).
os.makedirs("path/to/directory", exist_ok=True) # succeeds even if directory exists.
Patikrinkite os.makedirs
: (Įsitikinama, kad visas kelias egzistuoja.)
Kad būtų atsižvelgta į tai, jog katalogas gali egzistuoti, sugaunama OSError
.
(Jei exist_ok
yra False
(numatytoji reikšmė), jei tikslinis katalogas jau egzistuoja, iškeliama OSError
.)
import os
try:
os.makedirs('./path/to/somewhere')
except OSError:
pass
Išbandykite funkciją os.path.exists
if not os.path.exists(dir):
os.mkdir(dir)