Yuvalanmış bir dizini nasıl güvenle oluşturabilirim?


4246

Bir dosyanın yazılacak dizinin var olup olmadığını kontrol etmenin ve yoksa Python kullanarak dizini oluşturmanın en zarif yolu nedir? İşte ne denedim:

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)

Her nasılsa, kaçırdım os.path.exists(teşekkürler kanja, Blair ve Douglas). Şimdi sahip olduğum şey bu:

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

Bunun "otomatik olarak" gerçekleşmesini sağlayan bir bayrak var mı?


27
Genel olarak dosya adında dizin bulunmadığı durumu hesaba katmanız gerekebilir. Makinemde dirname ('foo.txt') '' veriyor ve bu yok ve makedirs () işlevinin başarısız olmasına neden oluyor.
Brian Hawkins

11
Python 2.7'de os.path.mkdirmevcut değil. Öyle os.mkdir.
drevicko

6
yol varsa, sadece bir dizin olup olmadığını kontrol etmek için değil, normal bir dosya ya da başka bir nesne (birçok cevap bunu kontrol edin) ayrıca yazılabilir olup olmadığını kontrol etmek için gereklidir (Bunu kontrol eden bir cevap bulamadım)
miracle173

9
Dosya yolu dizesinin üst dizinlerini oluşturmak için buraya geldiyseniz p, işte kod snippet'im:os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)
Thamme Gowda

Yanıtlar:


5188

Python ≥ 3.5'te pathlib.Path.mkdirşunları kullanın :

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

Python'un daha eski sürümleri için, her biri küçük bir kusuru olan iyi niteliklere sahip iki cevap görüyorum, bu yüzden onu ele alacağım:

Deneyin os.path.existsve os.makedirsyaratmayı düşünün .

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

Yorumların ve başka yerlerde belirtildiği gibi, bir yarış durumu var - dizin arasında oluşturulursa os.path.existsve os.makedirsçağrılar, os.makedirsbir başarısız olur OSError. Ne yazık ki, battaniye yakalama OSErrorve devam etme, yetersiz izinler, tam disk vb.Gibi diğer faktörler nedeniyle dizin oluşturma hatasını göz ardı edeceğinden kusursuz değildir.

Bir seçenek OSError, gömülü hata kodunu yakalamak ve incelemek olacaktır (bkz . Python'un OSError'undan bilgi almanın platformlar arası bir yolu var mı? ):

import os, errno

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

Alternatif olarak, bir saniye olabilir os.path.exists, ancak ilk kontrolden sonra başka bir dizin oluşturduğunu, sonra ikinci kontrolden önce kaldırdığını varsayalım - yine de kandırabiliriz.

Uygulamaya bağlı olarak, eşzamanlı işlem tehlikesi, dosya izinleri gibi diğer faktörlerin oluşturduğu tehlikeden daha fazla veya daha az olabilir. Bir uygulama seçmeden önce geliştiricinin geliştirilmekte olan belirli uygulama ve beklenen ortamı hakkında daha fazla bilgi sahibi olması gerekir.

Python'un modern sürümleri bu kodu biraz açığa çıkarır, hem de FileExistsError(3.3 + 'da) ...

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

... ve bir anahtar kelime bağımsız değişkeninin os.makedirsçağrılmasınaexist_ok izin vererek (3.2+).

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

5
Yarış koşulu iyi bir noktadır, ancak stackoverflow.com/questions/273192/#273208'deki yaklaşım , dizini oluşturmadaki bir başarısızlığı maskeleyecektir. Oy vermek için kötü hissetme - cevabı sevmiyorsun. Oylar bunun için.
Blair Conrad

27
Os.path.exists () öğesinin ücretsiz olmadığını unutmayın. Normal durum dizinin orada olacağı durumuysa, dizinin bulunmadığı durum bir istisna olarak ele alınmalıdır. Başka bir deyişle, dosyanızı açıp yazmaya çalışın, OSError istisnasını yakalayın ve errno'ya dayalı olarak makedir () 'i yapın ve yeniden deneyin veya yeniden yükseltin. Yazma yerel bir yöntemle sarmadıkça bu kod çoğaltılması oluşturur.
Andrew

22
os.path.existsayrıca Truebir dosya için döner . Bunu ele almak için bir cevap gönderdim.
Acumenus

13
Buradaki diğer cevaplara yorum yapanların belirttiği gibi, Python 3.2'den bu yana yolun önceden varlığının nasıl ele alınacağını kapsayacak şekilde kullanılabilecek exists_okparametre os.makedirs().
Bobble

6
os.mkdirs()bir yol ayırıcı yanlışlıkla dışarıda bırakılırsa, geçerli klasör beklendiği gibi değilse, bir yol öğesi yol ayırıcı içerir. os.mkdir()Bu hataları kullanırsanız , sizi varoldukları konusunda uyaran bir istisna ortaya çıkar.
drevicko

1241

Python 3.5+:

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

pathlib.Path.mkdirYukarıda kullanıldığı gibi dizini özyinelemeli olarak oluşturur ve dizin zaten varsa bir istisna oluşturmaz. Ebeveynlerin oluşturulmasını istemiyorsanız veya istemiyorsanız, parentsargümanı atlayın .

Python 3.2+:

Kullanma pathlib:

Yapabiliyorsanız, pathlibadlı geçerli backport'u yükleyin pathlib2. Adsız eski bakımı yapılmamış backport'u yüklemeyin pathlib. Ardından, yukarıdaki Python 3.5+ bölümüne bakın ve aynı şekilde kullanın.

Python 3.4 kullanıyorsanız, birlikte gelmesine rağmen pathlib, kullanışlı exist_okseçeneği eksik . Backport, mkdirbu eksik seçeneği içeren daha yeni ve üstün bir uygulama sunmayı amaçlamaktadır .

Kullanma os:

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

os.makedirsYukarıda kullanıldığı gibi dizini özyinelemeli olarak oluşturur ve dizin zaten varsa bir istisna oluşturmaz. exist_okYalnızca Python 3.2+ kullanılıyorsa, varsayılan değeri olan isteğe bağlı bağımsız değişkeni vardır False. Bu argüman Python 2.x'te 2.7'ye kadar mevcut değildir. Bu nedenle, Python 2.7'de olduğu gibi manuel istisna işlemeye gerek yoktur.

Python 2.7+:

Kullanma pathlib:

Yapabiliyorsanız, pathlibadlı geçerli backport'u yükleyin pathlib2. Adsız eski bakımı yapılmamış backport'u yüklemeyin pathlib. Ardından, yukarıdaki Python 3.5+ bölümüne bakın ve aynı şekilde kullanın.

Kullanma os:

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

Saf bir çözelti ilk kullanım olsa da os.path.isdir, ardından os.makedirsgeri dönüş sağlayarak iki işlem sırası üzerinde çözeltisi. Bunu yaparken, dizin oluşturma konusunda yinelenen bir girişim ile ilgili ortak bir yarış koşulunu önler ve ayrıca dosyaları dizinlerden ayırır.

Özel durumun yakalanmasının ve kullanılmasının errnosınırlı bir yararlılığı olduğuna dikkat edin OSError: [Errno 17] File exists, yani errno.EEXISThem dosyalar hem de dizinler için geliştirilmiştir. Dizinin var olup olmadığını kontrol etmek daha güvenilirdir.

Alternatif:

mkpathyuvalanmış dizini oluşturur ve dizin zaten varsa hiçbir şey yapmaz. Bu hem Python 2 hem de 3'te çalışır.

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

Başına Bug 10948 , bu alternatifin ciddi sınırlama verilen bir yol için piton sürecinin başına sadece bir kez çalışmasıdır. Başka bir deyişle, bir dizin oluşturmak için kullanırsanız, dizini Python'un içinden veya dışından silin, ardından mkpathaynı dizini yeniden oluşturmak için tekrar mkpathkullanın, dizini önceden oluşturmuş olan geçersiz önbelleğe alınmış bilgisini sessizce kullanır ve aslında dizini tekrar yapın. Buna karşılık, os.makedirsböyle bir önbelleğe güvenmez. Bu sınırlama bazı uygulamalar için uygun olabilir.


Yönetmenin modu ile ilgili olarak , lütfen önemsiyorsanız belgelere bakın.


13
Bu cevap, söyleyebildiğim kadarıyla hemen hemen her özel durumu kapsıyor. Ben dizinin hemen hemen her zaman var olmasını bekliyorum ve ben bu şekilde istisnayı önleyebilirsiniz çünkü bu "os.path.isdir ()" değilse sarma planlıyoruz.
Charles

5
@CharlesL. Nedeni performans ise, bir istisna, kontrolün disk IO'sundan daha ucuzdur.
jpmc26

1
@ jpmc26 ama makedirs sadece OSError atmayı kontrol ederken ek stat, umask, lstat yapar.
kwarunek

4
Potansiyel bir FS yarışı koşulu getirdiğinden, bu yanlış cevaptır. Aaron Hall'ın cevabına bakınız.
sleepycal

4
@sleepycal'ın dediği gibi, bu kabul edilen cevapla benzer bir yarış durumundan muzdariptir. Hatayı yükseltme ile os.path.isdirbaşka birini kontrol etme arasında klasör silinirse, o klasördeki yanlış, güncel olmayan ve kafa karıştırıcı hatayı yükseltirsiniz.
farmir

604

Errno modülündeki try ve doğru hata kodunu kullanmak yarış koşulundan kurtulur ve çapraz platformdur:

import os
import errno

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

Başka bir deyişle, dizinleri oluşturmaya çalışıyoruz, ancak zaten varsa, hatayı görmezden geliriz. Diğer yandan, diğer hatalar bildirilir. Örneğin, önceden 'a' dizini oluşturup ondan tüm izinleri kaldırırsanız, (İzin reddedildi, hata 13) OSErrorile yükseltilirsiniz errno.EACCES.


24
Kabul edilen cevap aslında tehlikelidir çünkü bir yarış durumu vardır. Bununla birlikte, daha basittir, bu yüzden yarış koşulunun farkında değilseniz veya sizin için geçerli olmayacağını düşünüyorsanız, bu sizin ilk seçiminiz olacaktır.
Heikki Toivonen

15
Kural exception.errno != errno.EEXISTdışı durum yalnızca, yol bulunduğunda kasayı istemeden yok sayar ancak dosya gibi dizin olmayan bir nesne olduğunda. Yol dizin olmayan bir nesne ise, istisna ideal olarak yükseltilmelidir.
Acumenus

178
Not Yukarıdaki kodu eşdeğer olduğuos.makedirs(path,exist_ok=True)
Navin

58
@Navin exist_okParametre Python 3.2'de tanıtıldı. Python 2.x'te mevcut değildir. Cevabımla birleştireceğim.
Acumenus

26
@HeikkiToivonen Teknik olarak konuşursak, başka bir program dizinleri ve dosyaları programınız aynı anda değiştiriyorsa, tüm programınız dev bir yarış koşuludur. Başka bir programın kod oluşturduktan sonra ve dosyaları gerçekten koymadan önce bu dizini silmesini engellemek için ne yapmalısınız?
jpmc26

102

Şahsen os.path.isdir()test etmek için kullanmanızı tavsiye ederim 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

Eğer varsa:

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

Ve aptal bir kullanıcı girişi:

:: /tmp/dirname/filename.etc

... Bu filename.etcargümanı os.makedirs()test ettiğinizde geçtiğinizde adlı bir dizin ile sonuçlanacaksınız os.path.exists().


8
Yalnızca 'isdir' kullanırsanız, dizini oluşturmaya çalıştığınızda hala bir sorununuz olmaz mı ve aynı ada sahip bir dosya zaten var mı?
MrWonderful

3
@MrWonderful Varolan bir dosya üzerinde dizin oluştururken ortaya çıkan kural dışı durum, sorunu arayan kişiye doğru bir şekilde yansıtacaktır.
Damian Yerrick

79

Kontrol edin os.makedirs: (Tam yolun mevcut olduğundan emin olur.)
Dizinin var olabileceği gerçeğini işlemek için, yakalayın OSError. (Eğer exist_okbir Falsebir,) varsayılan ( OSErrorhedef dizin zaten varsa yükseltilir.)

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

19
try / haricinde, dizin oluşturma durumundaki hataları maskeleyeceksiniz, dizinin mevcut olmadığı durumlarda, ancak bazı nedenlerle bunu yapamazsınız
Blair Conrad

3
OSErroryol mevcut bir dosya veya dizinse burada yükseltilir. Bunu ele almak için bir cevap gönderdim.
Acumenus

4
Bu orada. OSErrorYoksaymaya karar vermeden önce alt hata durumunu kontrol etmeniz gerekir . Bkz. Stackoverflow.com/a/5032238/763269 .
Chris Johnson

71

Python 3.5'ten başlayarak pathlib.Path.mkdir, bir exist_okbayrağı vardır:

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

Bu, özyinelemeli olarak dizini oluşturur ve dizin zaten varsa bir özel durum oluşturmaz.

(tıpkı python 3.2'den başlayan os.makedirsbir exist_okbayrak gibi os.makedirs(path, exist_ok=True))


46

Bu durumla ilgili ayrıntılar

Belirli bir dosyaya belirli bir yol verir ve dizini dosya yolundan alırsınız. Sonra dizine sahip olduğunuzdan emin olduktan sonra okumak için bir dosya açmaya çalışın. Bu kod hakkında yorum yapmak için:

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

Yerleşik işlevin üzerine yazmaktan kaçınmak istiyoruz dir. Ayrıca, filepathya da belki de fullfilepathdaha iyi bir anlamsal ad filenamebu yüzden daha iyi yazılır:

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

Son hedefiniz, başlangıçta yazmak için bu dosyayı açmaktır, ancak aslında bu hedefe (kodunuza göre) şu şekilde yaklaşırsınız, bu dosyayı okumak için açar :

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

Okumak için açık olduğu varsayılarak

Neden orada olmasını ve okunmasını beklediğiniz bir dosya için bir dizin oluşturuyorsunuz?

Sadece dosyayı açmayı deneyin.

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

Dizin veya dosya orada değilse, IOErrorilişkili bir hata numarasına sahip olacaksınız : errno.ENOENTplatformunuzdan bağımsız olarak doğru hata numarasını gösterecektir. İsterseniz yakalayabilirsiniz, örneğin:

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

Yazmaya açtığımızı varsayarsak

Bu muhtemelen size isteyen konum.

Bu durumda, muhtemelen herhangi bir yarış koşuluyla karşı karşıya değiliz. Öyleyse sadece yaptığınız gibi yapın, ancak yazmak için wmodla (veya aeklemek için) açmanız gerektiğini unutmayın . Ayrıca, dosyaları açmak için bağlam yöneticisini kullanmak en iyi Python uygulamasıdır.

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

Ancak, tüm verilerini aynı dizine koymaya çalışan birkaç Python işlemimiz olduğunu varsayalım. Sonra dizinin oluşturulması konusunda çekişebiliriz. Bu durumda, makedirsaramayı bir dene-hariç blokta sarmak en iyisidir .

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

os.path.existsİşlevi dene

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

3
Soru hakkında yorum yapacaktım, ama os.mkdir demek istiyor muyuz? Benim piton (2.5.2) hiçbir os.path.mkdir ....
Blair Conrad

1
Bir os.path.mkdir()yöntem yok . os.path modülü yol adları üzerinde bazı yararlı işlevler uygular .
Serge S.

31

Aşağıdakileri bıraktım. Tamamen kusursuz değildir.

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

Dediğim gibi, bu gerçekten kusursuz değil, çünkü dizini ve bu dönemde onu oluşturan başka bir işlemi yaratma olanağımız var.



İki sorun: (1) kontrol etmeye karar vermeden önce OSError alt hata durumunu kontrol etmeniz gerekir os.path.exists- bkz. Stackoverflow.com/a/5032238/763269 ve (2) açık os.path.existsdizinin var olduğu anlamına gelmez, sadece yol var - bir dosya, bir sembolik bağlantı veya başka bir dosya sistemi nesnesi olabilir.
Chris Johnson

24

Bir dizinin mevcut olup olmadığını kontrol edin ve gerekiyorsa oluşturun?

Bunun doğrudan cevabı, diğer kullanıcıların veya işlemlerin dizininizle uğraşmasını beklemediğiniz basit bir durum olduğunu varsayar:

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

veya dizini yapmak yarış koşullarına tabi ise (yani, yolu kontrol ettikten sonra, başka bir şey zaten yapmış olabilir) bunu yapın:

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

Ancak belki de daha iyi bir yaklaşım, geçici dizinleri kullanarak kaynak çekişme sorununu ortadan kaldırmaktır tempfile:

import tempfile

d = tempfile.mkdtemp()

Online dokümanın temel bilgileri:

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.

Python 3.5 yenilikler: pathlib.Pathileexist_ok

Biri Pathyollarla kullanmak isteyecek birçok yöntem içeren yeni bir nesne (3.4'ten itibaren) var mkdir.

(Bağlam için, haftalık temsilcimi bir komut dosyasıyla izliyorum. İşte, aynı veri için günde bir kereden fazla Stack Overflow'a çarpmama izin veren koddaki ilgili kod parçaları.)

İlk olarak ilgili ithalatlar:

from pathlib import Path
import tempfile

os.path.joinŞimdi uğraşmak zorunda değiliz - sadece yol parçalarına aşağıdakilerle katılın /:

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

Sonra idempotently dizini var sağlamak - exist_okargüman Python 3.5 görünür:

directory.mkdir(exist_ok=True)

İşte belgelerin ilgili kısmı :

exist_okTrue olursa , FileExistsErroristisnalar yok sayılır ( POSIX mkdir -pkomutla aynı davranış ), ancak yalnızca son yol bileşeni varolan bir dizin dışı dosya değilse.

İşte senaryo biraz daha - benim durumumda, bir yarış koşuluna tabi değilim, sadece dizinin (veya içerdiği dosyaları) orada olmasını bekleyen bir işlemim var ve kaldırmaya çalışan bir şeyim yok Rehber.

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))

Pathnesnelerin, yolları kullanabilmelerini strbekleyen diğer API'lerden önce zorlanmaları strgerekir.

Belki de Pandalar soyut temel sınıfın örneklerini kabul edecek şekilde güncellenmelidir os.PathLike.


20

Python 3.4'te yepyeni pathlibmodülü de kullanabilirsiniz :

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 yeni backport'tur. Büyük olanı korunmaz.
Acumenus

Benioku dosyasının ilk satırında belirttiği gibi, P. Ancak eski backport buradaki cevap için hala geçerli. Ve baş ağrısını adlandırmak yok. Neden ve ne zaman yeni kullanıcılar için pathlibnerede ve nerede açıklamak gerek yok pathlib2, ve bence burada profesyoneller artıları anlayacak;)
Janusz Skonieczny

13

İlgili Python belgelerine kullanımını önermektedir (mağfiret daha izin isteyin daha kolay) tarzı kodlama EAFP . Bu, kodun

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

alternatiften daha iyidir

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

Dokümantasyon bunu tam olarak bu soruda tartışılan yarış durumu nedeniyle önermektedir. Ayrıca, burada belirtildiği gibi, iki kez işletim sistemi yerine bir kez sorgulamada bir performans avantajı vardır. Son olarak, bazı durumlarda - geliştiricinin uygulamanın çalıştığı ortamı bildiği zaman - potansiyel olarak ikinci kod lehine ileri sürülen argüman, yalnızca programın özel bir ortam oluşturduğu özel durumda (ve aynı programın diğer örnekleri).

Bu durumda bile, bu kötü bir uygulamadır ve uzun süre gereksiz hata ayıklamaya yol açabilir. Örneğin, bir dizin için izinleri belirlediğimiz gerçeği bizi gösterim izinleri amacımız için uygun şekilde ayarlanmış olarak bırakmamalıdır. Bir üst dizin diğer izinlerle bağlanabilir. Genel olarak, bir program her zaman doğru çalışmalı ve programcı belirli bir ortam beklememelidir.


11

In Python3 , os.makedirsdestekler ayarı exist_ok. Varsayılan ayar, hedef dizin zaten varsa bir yükseltilecek Falseanlamına gelir OSError. Ayarlayarak exist_okiçin True, OSError(dizinin mevcut) göz ardı edilir ve dizin oluşturulmaz.

os.makedirs(path,exist_ok=True)

In Python2 , os.makedirsayarı desteklemiyor exist_ok. Heikki-toivonen'in cevabındaki yaklaşımı kullanabilirsiniz :

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

Tek astarlı bir çözüm için şunları kullanabilirsiniz IPython.utils.path.ensure_dir_exists():

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

Gönderen belgeler : Bir dizin var olduğundan emin olun. Eğer yoksa, başka bir işlem de aynısını yapıyorsa, onu yaratmaya ve yarış koşullarına karşı korumaya çalışın.


Yeni IPython belgeleri burada mevcuttur .
jkdev

3
IPythonModül kesinlikle mevcut olması garanti edilmez. Mac'imde doğal olarak mevcut, ancak Python'un Linux kurulumlarının hiçbirinde yok. Temel olarak, Python Modül İndeksinde listelenen modüllerden biri değildir .
Acumenus

1
Elbette. Paketi kurmak için, olağan olanı çalıştırmanız pip install ipythonveya gereksinimlerinize bağımlılığı eklemeniz yeterlidir . Txt veya pom.xml . Belgeler: ipython.org/install.html
tashuhka

9

Kullanabilirsiniz mkpath

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

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

Ayrıca ata dizinlerini de oluşturacağını unutmayın.

Python 2 ve 3 için çalışır.


2
distutils.dir_utildistutil genel API'sinin bir parçası değildir ve çok iş parçacıklı ortamlarda sorunları vardır: bugs.python.org/issue10948
Pod

1
Evet. Hatanın ilk iletisinde belirtildiği gibi sorun, distutils.dir_util.mkpathbir dizin oluşturursanız, onu Python'un içinden veya dışından silerseniz, daha sonra mkpathtekrar mkpathkullanmanız, dizini önceden oluşturmuş olan geçersiz önbelleğe alınmış bilgisini kullanması ve dizini yeniden oluşturmaz. Buna karşılık, os.makedirsböyle bir önbelleğe güvenmez.
Acumenus

8

Kullanıyorum os.path.exists(), burada bir dizin olup olmadığını kontrol etmek için kullanılabilecek bir Python 3 senaryo, o yoksa bir tane oluşturun ve (istenirse) versiyonu varsa silin.

Kullanıcılardan dizinin girilmesini ister ve kolayca değiştirilebilir.


6

Bunun için kullanabilirsiniz os.listdir:

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

Bu soruya cevap vermiyor
Georgy

6

Bu Q / A buldum ve başlangıçta aldığım bazı hatalar ve hatalar tarafından şaşırdım. Python 3'te (Arch Linux x86_64 sisteminde Anaconda sanal ortamında v.3.5) çalışıyorum.

Bu dizin yapısını göz önünde bulundurun:

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

İşte bazı şeyleri netleştiren deneylerim / notlarım:

# ----------------------------------------------------------------------------
# [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
# ----------------------------------------------------------------------------

Sonuç: Bence "Yöntem 2" daha sağlam.

[1] Varsa bir dizini nasıl oluşturabilirim?

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


6

Heikki Toivonen ve ABB'nin cevaplarını gördüm ve bu varyasyonu düşündüm.

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


5

Destekleri komutu bir makinede çalışan eğer Neden altişlem modülü kullanmak mkdirile -pseçeneğiyle? Python 2.7 ve python 3.6 üzerinde çalışır

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

Çoğu sistemde hile yapmalı.

Taşınabilirliğin önemli olmadığı durumlarda (örn. Liman işçisini kullanarak) çözüm temiz 2 satırdır. Ayrıca dizinlerin var olup olmadığını kontrol etmek için mantık eklemeniz gerekmez. Son olarak, herhangi bir yan etki olmadan yeniden çalıştırmak güvenlidir

Hata işlemeye ihtiyacınız varsa:

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

4

Aşağıdakileri dikkate alırsanız:

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

bir dizin (yol) var demektir VE bir dizindir. Yani benim için bu şekilde ihtiyacım olanı yapıyor. Böylece klasör (dosya değil) ve var olduğundan emin olabilirim.


Bu nasıl bir dizin oluşturma sorusunu cevaplıyor ?
Georgy

3

create_dir()Programınızın / projenizin giriş noktasındaki işlevi çağırın .

import os

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

create_dir('Project directory')

3

Dizini oluşturmadan önce tam yolu ayarlamanız gerekir:

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)

Bu benim için çalışıyor ve umarım sizin için de çalışır


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

Kodunuzun bulunduğu yer (touch) komutunu kullanın

Bu, dosyanın orada olup olmadığını kontrol edecektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.