Come posso creare in modo sicuro una directory nidificata?


4249

Qual è il modo più elegante per verificare se la directory in cui verrà scritto un file esiste e, in caso contrario, creare la directory usando Python? Ecco cosa ho provato:

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)

In qualche modo, mi mancava os.path.exists(grazie Kanja, Blair e Douglas). Questo è quello che ho ora:

def ensure_dir(file_path):
    directory = os.path.dirname(file_path)
    if not os.path.exists(directory):
        os.makedirs(directory)

C'è una bandiera per "aperto", che fa sì che ciò accada automaticamente?


27
In generale potrebbe essere necessario tenere conto del caso in cui non esiste una directory nel nome file. Sulla mia macchina dirname ('foo.txt') dà '', che non esiste e fa fallire makedirs ().
Brian Hawkins,

11
In Python 2.7 os.path.mkdirnon esiste. Lo è os.mkdir.
drevicko,

6
se il percorso esiste non si deve solo verificare se si tratta di una directory e non di un file normale o di un altro oggetto (molte risposte lo verificano) è anche necessario verificare se è scrivibile (non ho trovato una risposta che ha verificato questo)
miracle173,

9
Nel caso in cui tu venissi qui per creare directory padre della stringa del percorso del file p, ecco il mio frammento di codice:os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)
Thamme Gowda,

Risposte:


5193

Su Python ≥ 3.5, utilizzare pathlib.Path.mkdir:

from pathlib import Path
Path("/my/directory").mkdir(parents=True, exist_ok=True)

Per le versioni precedenti di Python, vedo due risposte con buone qualità, ognuna con un piccolo difetto, quindi darò la mia opinione su di essa:

Prova os.path.existse considera os.makedirsla creazione.

import os
if not os.path.exists(directory):
    os.makedirs(directory)

Come notato nei commenti e altrove, c'è una condizione di competizione: se la directory viene creata tra os.path.existsle os.makedirschiamate e, os.makedirsfallirà con un OSError. Sfortunatamente, accattivanteOSError e il proseguimento delle non è infallibile, poiché ignorerà un errore nella creazione della directory a causa di altri fattori, come autorizzazioni insufficienti, disco intero, ecc.

Un'opzione sarebbe quella di intercettare OSErrored esaminare il codice di errore incorporato (vedere Esiste un modo multipiattaforma per ottenere informazioni dall'errore di errore di Python ):

import os, errno

try:
    os.makedirs(directory)
except OSError as e:
    if e.errno != errno.EEXIST:
        raise

In alternativa, potrebbe esserci un secondo os.path.exists, ma supponiamo che un altro abbia creato la directory dopo il primo controllo, quindi l'ha rimossa prima del secondo - potremmo ancora essere ingannati.

A seconda dell'applicazione, il pericolo di operazioni simultanee può essere maggiore o minore del pericolo rappresentato da altri fattori come le autorizzazioni per i file. Lo sviluppatore dovrebbe sapere di più sulla particolare applicazione in fase di sviluppo e sul suo ambiente previsto prima di scegliere un'implementazione.

Le versioni moderne di Python migliorano un po 'questo codice, sia esponendo FileExistsError(in 3.3+) ...

try:
    os.makedirs("path/to/directory")
except FileExistsError:
    # directory already exists
    pass

... e consentendo la chiamata di un argomento di parole chiaveos.makedirsexist_ok (in 3.2+).

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.

5
Le condizioni di gara sono un buon punto, ma l'approccio in stackoverflow.com/questions/273192/#273208 nasconderà un errore nella creazione della directory. Non sentirti male per votare in basso - non ti piace la risposta. È a cosa servono i voti.
Blair Conrad,

27
Ricorda che os.path.exists () non è gratuito. Se il caso normale è che la directory sarà lì, il caso in cui non è dovrebbe essere gestito come un'eccezione. In altre parole, prova ad aprire e scrivere sul tuo file, prendi l'eccezione OSError e, in base a errno, esegui il tuo makedir () e riprova o ri-rilancia. Ciò crea la duplicazione del codice a meno che non si impacchetta la scrittura in un metodo locale.
Andrew,

22
os.path.existsrestituisce anche Trueper un file. Ho inviato una risposta per rispondere a questo.
Acumenus,

13
Come hanno notato i commentatori di altre risposte qui, il exists_okparametro to os.makedirs()può essere usato per coprire come viene gestita la precedente esistenza del percorso, da Python 3.2.
Bobble,

6
os.mkdirs()può creare cartelle indesiderate se un separatore di percorso viene accidentalmente escluso, la cartella corrente non è come previsto, un elemento del percorso contiene il separatore di percorso. Se usi os.mkdir()questi bug genererà un'eccezione, avvisandoti della loro esistenza.
drevicko,

1242

Python 3.5+:

import pathlib
pathlib.Path('/my/directory').mkdir(parents=True, exist_ok=True) 

pathlib.Path.mkdircome usato sopra crea ricorsivamente la directory e non genera un'eccezione se la directory esiste già. Se non hai bisogno o desideri che i genitori vengano creati, salta il fileparents argomento.

Python 3.2+:

Utilizzando pathlib:

Se possibile, installare il pathlibbackport corrente denominato pathlib2. Non installare il vecchio backport non mantenuto denominato pathlib. Quindi, fai riferimento alla precedente sezione Python 3.5+ e usala allo stesso modo.

Se si utilizza Python 3.4, anche se viene fornito pathlib, manca l' exist_okopzione utile . Il backport ha lo scopo di offrire un'implementazione più recente e superiore mkdirche include questa opzione mancante.

Utilizzando os:

import os
os.makedirs(path, exist_ok=True)

os.makedirscome usato sopra crea ricorsivamente la directory e non genera un'eccezione se la directory esiste già. Ha l' exist_okargomento opzionale solo se si utilizza Python 3.2+, con un valore predefinito diFalse . Questo argomento non esiste in Python 2.x fino a 2.7. Pertanto, non è necessario gestire manualmente le eccezioni come con Python 2.7.

Python 2.7+:

Utilizzando pathlib:

Se possibile, installare il pathlibbackport corrente denominato pathlib2. Non installare il vecchio backport non mantenuto denominato pathlib. Quindi, fai riferimento alla precedente sezione Python 3.5+ e usala allo stesso modo.

Utilizzando os:

import os
try: 
    os.makedirs(path)
except OSError:
    if not os.path.isdir(path):
        raise

Mentre una soluzione ingenua può prima usare os.path.isdirseguita da os.makedirs, la soluzione sopra inverte l'ordine delle due operazioni. In tal modo, impedisce una condizione di competizione comune a che fare con un tentativo duplicato di creare la directory e disambigua anche i file dalle directory.

Si noti che la cattura dell'eccezione e l'utilizzo errnoè di utilità limitata perché OSError: [Errno 17] File exists, ad esempio errno.EEXIST, viene generato sia per i file che per le directory. È più affidabile semplicemente verificare se la directory esiste.

Alternativa:

mkpathcrea la directory nidificata e non fa nulla se la directory esiste già. Funziona con Python 2 e 3.

import distutils.dir_util
distutils.dir_util.mkpath(path)

Per Bug 10948 , una grave limitazione di questa alternativa è che funziona solo una volta per processo Python per un determinato percorso. In altre parole, se lo si utilizza per creare una directory, quindi si elimina la directory dall'interno o dall'esterno di Python, quindi si utilizza di mkpathnuovo per ricreare la stessa directory, mkpathsi limiterà a utilizzare silenziosamente le informazioni memorizzate nella cache non valide di aver creato la directory in precedenza e non effettivamente rendere nuovamente la directory. Al contrario, os.makedirsnon si basa su tale cache. Questa limitazione potrebbe andare bene per alcune applicazioni.


Per quanto riguarda la modalità della directory , consultare la documentazione se ci si preoccupa.


13
Questa risposta copre praticamente ogni caso speciale per quanto posso dire. Ho intenzione di racchiuderlo in un "if not os.path.isdir ()" anche se mi aspetto che la directory esista quasi ogni volta e posso evitare l'eccezione in quel modo.
Charles L.

5
@CharlesL. Un'eccezione è probabilmente più economica dell'IO del disco del controllo, se il motivo è la prestazione.
jpmc26,

1
@ jpmc26 ma makedirs fa stat, umask, lstat aggiuntivi quando controlla solo per lanciare OSError.
Kwarunek,

4
Questa è la risposta sbagliata, in quanto introduce un potenziale cond di gara FS. Vedi la risposta di Aaron Hall.
sleepycal

4
come ha detto @sleepycal, questo soffre di una condizione di razza simile alla risposta accettata. Se tra la segnalazione dell'errore e il controllo di os.path.isdirqualcun altro si cancella la cartella, si genererà l'errore errato, obsoleto e confuso in quella cartella.
farmir

604

Usando try etc e il giusto codice di errore dal modulo errno elimina le condizioni di gara ed è multipiattaforma:

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise

In altre parole, proviamo a creare le directory, ma se esistono già ignoriamo l'errore. D'altra parte, viene segnalato qualsiasi altro errore. Ad esempio, se si crea prima dir 'a' e si rimuovono tutte le autorizzazioni da esso, si otterrà unOSError rilancio con errno.EACCES(Autorizzazione negata, errore 13).


24
La risposta accettata è in realtà pericolosa perché ha una condizione di razza. Tuttavia, è più semplice, quindi se non sei a conoscenza delle condizioni di gara o pensi che non si applicherebbe a te, questa sarebbe la tua prima scelta ovvia.
Heikki Toivonen,

15
Sollevando l'eccezione solo quando exception.errno != errno.EEXISTsi ignorerà involontariamente il caso in cui esiste un percorso ma si tratta di un oggetto non di directory come un file. L'eccezione dovrebbe idealmente essere sollevata se il percorso è un oggetto non di directory.
Acumenus,

178
Si noti che il codice sopra è equivalente aos.makedirs(path,exist_ok=True)
Navin

58
@Navin Il exist_okparametro è stato introdotto in Python 3.2. Non è presente in Python 2.x. Lo incorporerò nella mia risposta.
Acumenus,

26
@HeikkiToivonen Tecnicamente parlando, se un altro programma sta modificando le directory e i file nello stesso momento in cui lo è il tuo programma, l'intero programma è una gigantesca condizione di gara. Cosa impedisce a un altro programma di eliminare questa directory solo dopo che il codice è stato creato e prima di inserirvi effettivamente i file?
jpmc26,

102

Raccomanderei personalmente di usare os.path.isdir()per testare invece di os.path.exists().

>>> os.path.exists('/tmp/dirname')
True
>>> os.path.exists('/tmp/dirname/filename.etc')
True
>>> os.path.isdir('/tmp/dirname/filename.etc')
False
>>> os.path.isdir('/tmp/fakedirname')
False

Se hai:

>>> dir = raw_input(":: ")

E un input utente sciocco:

:: /tmp/dirname/filename.etc

... Finirai con una directory chiamata filename.etcquando passi quell'argomento os.makedirs()se provi con os.path.exists().


8
Se usi solo 'isdir', non avrai ancora problemi quando provi a creare la directory ed esiste già un file con lo stesso nome?
MrWonderful,

3
@MrWonderful L'eccezione risultante durante la creazione di una directory su un file esistente rispecchierebbe correttamente il problema al chiamante.
Damian Yerrick,

79

Controllare os.makedirs: (Si assicura che esista il percorso completo.)
Per gestire il fatto che la directory potrebbe esistere, prendere OSError. (Se exist_okè False(impostazione predefinita), OSErrorviene sollevato se la directory di destinazione esiste già.)

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass

19
con il tentativo / tranne, maschererai gli errori nella creazione della directory, nel caso in cui la directory non esistesse ma per qualche motivo non puoi farcela
Blair Conrad

3
OSErrorverrà generato qui se il percorso è un file o una directory esistente. Ho inviato una risposta per rispondere a questo.
Acumenus,

4
Questo è a metà strada lì. È necessario controllare la condizione di errore secondario OSErrorprima di decidere di ignorarla. Vedi stackoverflow.com/a/5032238/763269 .
Chris Johnson,

71

A partire da Python 3.5, pathlib.Path.mkdirha un exist_okflag:

from pathlib import Path
path = Path('/my/directory/filename.txt')
path.parent.mkdir(parents=True, exist_ok=True) 
# path.parent ~ os.path.dirname(path)

Ciò crea ricorsivamente la directory e non genera un'eccezione se la directory esiste già.

(proprio come ha os.makedirsottenuto una exist_okbandiera a partire da Python 3.2 ad esempio os.makedirs(path, exist_ok=True))


46

Approfondimenti sui dettagli di questa situazione

Dai un determinato file in un determinato percorso e estrai la directory dal percorso del file. Quindi, dopo aver verificato di avere la directory, si tenta di aprire un file per la lettura. Per commentare questo codice:

filename = "/my/directory/filename.txt"
dir = os.path.dirname(filename)

Vogliamo evitare la sovrascrittura della funzione built-in, dir. Inoltre, filepatho forse fullfilepathè probabilmente un nome semantico migliore di filenamecosì sarebbe meglio scrivere questo:

import os
filepath = '/my/directory/filename.txt'
directory = os.path.dirname(filepath)

Il tuo obiettivo finale è quello di aprire questo file, inizialmente dichiarato, per la scrittura, ma essenzialmente ti stai avvicinando a questo obiettivo (basato sul tuo codice) in questo modo, che apre il file per la lettura :

if not os.path.exists(directory):
    os.makedirs(directory)
f = file(filename)

Supponendo l'apertura per la lettura

Perché dovresti creare una directory per un file che ti aspetti di essere lì e di poter leggere?

Tenta di aprire il file.

with open(filepath) as my_file:
    do_stuff(my_file)

Se la directory o il file non è presente, otterrai un IOErrornumero di errore associato: errno.ENOENTpunterà al numero di errore corretto indipendentemente dalla piattaforma. Puoi prenderlo se vuoi, ad esempio:

import errno
try:
    with open(filepath) as my_file:
        do_stuff(my_file)
except IOError as error:
    if error.errno == errno.ENOENT:
        print 'ignoring error because directory or file is not there'
    else:
        raise

Supponendo che stiamo aprendo per la scrittura

Questo è probabilmente quello che stai cercando.

In questo caso, probabilmente non stiamo affrontando alcuna condizione di gara. Quindi fai come eri, ma nota che per scrivere, devi aprire con la wmodalità (o aaggiungere). È anche una buona pratica di Python usare il gestore del contesto per aprire i file.

import os
if not os.path.exists(directory):
    os.makedirs(directory)
with open(filepath, 'w') as my_file:
    do_stuff(my_file)

Tuttavia, supponiamo di avere diversi processi Python che tentano di mettere tutti i loro dati nella stessa directory. Quindi potremmo avere controversie sulla creazione della directory. In tal caso, è consigliabile racchiudere la makedirschiamata in un blocco try-tranne.

import os
import errno
if not os.path.exists(directory):
    try:
        os.makedirs(directory)
    except OSError as error:
        if error.errno != errno.EEXIST:
            raise
with open(filepath, 'w') as my_file:
    do_stuff(my_file)

34

Prova la os.path.existsfunzione

if not os.path.exists(dir):
    os.mkdir(dir)

3
Stavo per commentare la domanda, ma intendiamo os.mkdir? Il mio pitone (2.5.2) non ha os.path.mkdir ....
Blair Conrad

1
Non esiste un os.path.mkdir()metodo Il modulo os.path implementa alcune utili funzioni sui nomi dei percorsi .
Serge S.

31

Ho messo giù quanto segue. Non è totalmente infallibile però.

import os

dirname = 'create/me'

try:
    os.makedirs(dirname)
except OSError:
    if os.path.exists(dirname):
        # We are nearly safe
        pass
    else:
        # There was an error on creation, so make sure we know about it
        raise

Ora, come ho detto, questo non è assolutamente infallibile, perché abbiamo la possibilità di non riuscire a creare la directory e un altro processo che la crea durante quel periodo.



Due problemi: (1) è necessario controllare la condizione di errore secondario di OSError prima di decidere di controllare os.path.exists- consultare stackoverflow.com/a/5032238/763269 e (2) il successo su os.path.existsnon significa che la directory esiste, solo che il percorso esiste - potrebbe essere un file, un collegamento simbolico o un altro oggetto del file system.
Chris Johnson,

24

Controllare se esiste una directory e crearla se necessario?

La risposta diretta a questo è, supponendo una semplice situazione in cui non ti aspetti che altri utenti o processi stiano scherzando con la tua directory:

if not os.path.exists(d):
    os.makedirs(d)

o se rendere la directory è soggetta alle condizioni di gara (cioè se dopo aver verificato il percorso esiste qualcos'altro che potrebbe averlo già fatto) fare questo:

import errno
try:
    os.makedirs(d)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise

Ma forse un approccio ancora migliore è quello di eludere il problema della contesa di risorse, usando directory temporanee tramite tempfile:

import tempfile

d = tempfile.mkdtemp()

Ecco gli elementi essenziali del documento online:

mkdtemp(suffix='', prefix='tmp', dir=None)
    User-callable function to create and return a unique temporary
    directory.  The return value is the pathname of the directory.

    The directory is readable, writable, and searchable only by the
    creating user.

    Caller is responsible for deleting the directory when done with it.

Novità in Python 3.5: pathlib.Pathconexist_ok

C'è un nuovo Pathoggetto (a partire da 3.4) con molti metodi che uno vorrebbe usare con i percorsi - uno dei quali è mkdir.

(Per il contesto, sto monitorando il mio rappresentante settimanale con uno script. Ecco le parti rilevanti del codice dello script che mi consentono di evitare di colpire Stack Overflow più di una volta al giorno per gli stessi dati.)

Innanzitutto le importazioni rilevanti:

from pathlib import Path
import tempfile

Non dobbiamo occuparci os.path.joinora, basta unire parti del percorso con un /:

directory = Path(tempfile.gettempdir()) / 'sodata'

Quindi mi assicuro idempotentemente che la directory esista - l' exist_okargomento si presenta in Python 3.5:

directory.mkdir(exist_ok=True)

Ecco la parte rilevante della documentazione :

Se exist_okè vero, le FileExistsErroreccezioni verranno ignorate (stesso comportamento del POSIX mkdir -pcomando), ma solo se l'ultimo componente del percorso non è un file non di directory esistente.

Ecco un po 'di più dello script: nel mio caso, non sono soggetto a una race condition, ho solo un processo che prevede che la directory (o i file contenuti) sia lì e non ho nulla che tenti di rimuovere la directory.

todays_file = directory / str(datetime.datetime.utcnow().date())
if todays_file.exists():
    logger.info("todays_file exists: " + str(todays_file))
    df = pd.read_json(str(todays_file))

Pathgli oggetti devono essere forzati strprima di altre API che si aspettanostr percorsi possano usarli.

Forse Panda dovrebbe essere aggiornato ad accettare le istanze della classe base astratta, os.PathLike.


20

In Python 3.4 puoi anche usare il nuovissimo pathlibmodulo :

from pathlib import Path
path = Path("/my/directory/filename.txt")
try:
    if not path.parent.exists():
        path.parent.mkdir(parents=True)
except OSError:
    # handle error; you can also catch specific errors like
    # FileExistsError and so on.

@JanuszSkonieczny pypi.python.org/pypi/pathlib2 è il backport più recente. Il più vecchio non è mantenuto.
Acumenus,

Come indicato nella prima riga del readme; P. Ma il vecchio backport è ancora valido per la risposta qui. E non c'è mal di testa per i nomi. Non c'è bisogno di spiegare perché e quando usare pathlibe dove pathlib2per i nuovi utenti, e penso che i professionisti qui
scopriranno

13

La documentazione di Python pertinente suggerisce l'uso dello stile di codifica EAFP (più facile chiedere perdono che autorizzazione) . Ciò significa che il codice

try:
    os.makedirs(path)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise
    else:
        print "\nBE CAREFUL! Directory %s already exists." % path

è migliore dell'alternativa

if not os.path.exists(path):
    os.makedirs(path)
else:
    print "\nBE CAREFUL! Directory %s already exists." % path

La documentazione suggerisce questo esattamente a causa delle condizioni di gara discusse in questa domanda. Inoltre, come altri citano qui, vi è un vantaggio in termini di prestazioni nell'interrogare una volta anziché due volte il sistema operativo. Infine, l'argomento avanzato, potenzialmente, a favore del secondo codice in alcuni casi - quando lo sviluppatore conosce l'ambiente in cui è in esecuzione l'applicazione - può essere sostenuto solo nel caso speciale in cui il programma ha impostato un ambiente privato per stesso (e altre istanze dello stesso programma).

Anche in questo caso, questa è una cattiva pratica e può portare a lunghi inutili debug. Ad esempio, il fatto che impostiamo le autorizzazioni per una directory non dovrebbe lasciarci con le autorizzazioni di impressione impostate in modo appropriato per i nostri scopi. Una directory padre potrebbe essere montata con altre autorizzazioni. In generale, un programma dovrebbe sempre funzionare correttamente e il programmatore non dovrebbe aspettarsi un ambiente specifico.


12

In Python3 , os.makedirssupporta l'impostazione exist_ok. L'impostazione predefinita è False, il che significa che OSErrorverrà sollevato se la directory di destinazione esiste già. Impostando exist_oksu True, OSError(la directory esiste) verrà ignorata e la directory non verrà creata.

os.makedirs(path,exist_ok=True)

In Python2 , os.makedirsnon supporta l'impostazione exist_ok. Puoi usare l'approccio nella risposta di heikki-toivonen :

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise

11

Per una soluzione one-liner, è possibile utilizzare IPython.utils.path.ensure_dir_exists():

from IPython.utils.path import ensure_dir_exists
ensure_dir_exists(dir)

Dalla documentazione : assicurarsi che esista una directory. Se non esiste, prova a crearlo e proteggilo da una condizione di competizione se un altro processo sta facendo lo stesso.


Nuova documentazione di IPython disponibile qui .
jkdev,

3
Non IPythonè assolutamente garantito che il modulo sia presente. È nativamente presente sul mio Mac, ma non su nessuna delle mie installazioni Linux di Python. Fondamentalmente, non è uno dei moduli elencati nell'indice del modulo Python .
Acumenus,

1
Sicuro. Per installare il pacchetto, esegui semplicemente il solito pip install ipythono includi la dipendenza nei tuoi requisiti.txt o pom.xml . Documentazione: ipython.org/install.html
tashuhka,

9

Puoi usare mkpath

# Create a directory and any missing ancestor directories. 
# If the directory already exists, do nothing.

from distutils.dir_util import mkpath
mkpath("test")    

Si noti che creerà anche le directory degli antenati.

Funziona con Python 2 e 3.


2
distutils.dir_utilnon fa parte dell'API pubblica distutil e presenta problemi in ambienti multi-thread: bugs.python.org/issue10948
Pod

1
Sì. Come notato nel primo messaggio del bug, il problema distutils.dir_util.mkpathè che se si crea una directory, quindi la si elimina da Python interna o esterna, quindi si utilizza di mkpathnuovo, mkpathverranno semplicemente utilizzate le informazioni memorizzate nella cache non valide di aver creato la directory in precedenza e in realtà non creare nuovamente la directory. Al contrario, os.makedirsnon si basa su tale cache.
Acumenus,

8

Io uso os.path.exists(), ecco uno script di Python 3 che può essere usato per verificare se esiste una directory, crearne una se non esiste ed eliminarla se esiste (se lo si desidera).

Richiede agli utenti l'inserimento della directory e può essere facilmente modificato.


6

Puoi usare os.listdirper questo:

import os
if 'dirName' in os.listdir('parentFolderPath')
    print('Directory Exists')

Questo non risponde alla domanda
Georgy,

6

Ho trovato questo Q / A e inizialmente ero perplesso da alcuni degli errori e degli errori che stavo riscontrando. Sto lavorando in Python 3 (v.3.5 in un ambiente virtuale Anaconda su un sistema Arch Linux x86_64).

Considera questa struttura di directory:

└── output/         ## dir
   ├── corpus       ## file
   ├── corpus2/     ## dir
   └── subdir/      ## dir

Ecco i miei esperimenti / note, che chiariscono le cose:

# ----------------------------------------------------------------------------
# [1] /programming/273192/how-can-i-create-a-directory-if-it-does-not-exist

import pathlib

""" Notes:
        1.  Include a trailing slash at the end of the directory path
            ("Method 1," below).
        2.  If a subdirectory in your intended path matches an existing file
            with same name, you will get the following error:
            "NotADirectoryError: [Errno 20] Not a directory:" ...
"""
# Uncomment and try each of these "out_dir" paths, singly:

# ----------------------------------------------------------------------------
# METHOD 1:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but no file created (os.makedirs creates dir, not files!  ;-)
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# [2] https://docs.python.org/3/library/os.html#os.makedirs

# Uncomment these to run "Method 1":

#directory = os.path.dirname(out_dir)
#os.makedirs(directory, mode=0o777, exist_ok=True)

# ----------------------------------------------------------------------------
# METHOD 2:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## works
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## works
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but creates a .../doc.txt./ dir
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# Uncomment these to run "Method 2":

#import os, errno
#try:
#       os.makedirs(out_dir)
#except OSError as e:
#       if e.errno != errno.EEXIST:
#               raise
# ----------------------------------------------------------------------------

Conclusione: a mio avviso, il "Metodo 2" è più solido.

[1] Come posso creare una directory se non esiste?

[2] https://docs.python.org/3/library/os.html#os.makedirs


6

Ho visto le risposte di Heikki Toivonen e ABB e ho pensato a questa variazione.

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST or not os.path.isdir(path):
            raise

6

Utilizzare questo controllo comandi e creare dir

 if not os.path.isdir(test_img_dir):
     os.mkdir(test_img_dir)

5

Perché non utilizzare il modulo di sottoprocesso se in esecuzione su una macchina che supporta il comando mkdircon -popzione? Funziona su Python 2.7 e Python 3.6

from subprocess import call
call(['mkdir', '-p', 'path1/path2/path3'])

Dovrebbe fare il trucco sulla maggior parte dei sistemi.

In situazioni in cui la portabilità non ha importanza (ad es. Utilizzando la finestra mobile) la soluzione è di 2 linee pulite. Inoltre, non è necessario aggiungere la logica per verificare l'esistenza o meno delle directory. Infine, è sicuro rieseguire senza effetti collaterali

Se è necessaria la gestione degli errori:

from subprocess import check_call
try:
    check_call(['mkdir', '-p', 'path1/path2/path3'])
except:
    handle...

4

Se si considera quanto segue:

os.path.isdir('/tmp/dirname')

significa che esiste una directory (percorso) AND è una directory. Quindi per me in questo modo fa quello che mi serve. Quindi posso assicurarmi che sia una cartella (non un file) ed esiste.


In che modo questo risponde a una domanda sulla creazione di una directory?
Georgy,

3

Chiamare la funzione create_dir()al punto di ingresso del programma / progetto.

import os

def create_dir(directory):
    if not os.path.exists(directory):
        print('Creating Directory '+directory)
        os.makedirs(directory)

create_dir('Project directory')

3

Devi impostare il percorso completo prima di creare la directory:

import os,sys,inspect
import pathlib

currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
your_folder = currentdir + "/" + "your_folder"

if not os.path.exists(your_folder):
   pathlib.Path(your_folder).mkdir(parents=True, exist_ok=True)

Questo funziona per me e, si spera, funzionerà anche per te


1
import os
if os.path.isfile(filename):
    print "file exists"
else:
    "Your code here"

Dove si trova il codice qui usa il comando (touch)

Questo verificherà se il file è presente se non lo è, quindi lo creerà.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.