splitext用法 - python3 os




如何在Python中安全地創建嵌套目錄? (17)

檢查目錄是否存在並在必要時創建它?

對此的直接回答是,假設您不希望其他用戶或進程弄亂您的目錄的簡單情況:

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

或者如果使目錄受到競爭條件的影響(即,如果檢查路徑存在後,還有其他東西可能已經成功),請執行以下操作:

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

但也許更好的方法是通過tempfile使用臨時目錄來迴避資源爭用問題:

import tempfile

d = tempfile.mkdtemp()

以下是在線文檔的基本要點:

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中的新功能:帶有exist_ok

有一個新的Path對象(截至3.4),有許多方法需要與路徑一起使用 - 其中一個是mkdir

(對於上下文,我使用腳本跟踪我的每周代表。這是腳本中代碼的相關部分,這些代碼允許我避免每天多次針對相同數據訪問Stack Overflow。)

首先是相關進口:

from pathlib import Path
import tempfile

我們現在不必處理os.path.join - 只需使用/連接路徑部分:

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

然後我exist_ok確保目錄存在 - 在Python 3.5中顯示exist_ok參數:

directory.mkdir(exist_ok=True)

這是pathlib.Path.mkdir的相關部分:

如果exist_ok為true, FileExistsError忽略FileExistsError異常(與POSIX mkdir -p命令相同的行為),但exist_ok是最後一個路徑組件不是現有的非目錄文件。

這裡有一些腳本 - 在我的情況下,我不受競爭條件的限制,我只有一個進程需要目錄(或包含文件),並且我沒有任何東西試圖刪除目錄。

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

在期望str路徑可以使用它們的其他API之前,必須將Path對象強制轉換為str

也許應該更新Pandas以接受抽象基類os.PathLike

https://code.i-harness.com

檢查文件目錄是否存在的最優雅方法是什麼,如果不存在,使用Python創建目錄? 這是我嘗試過的:

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)

不知怎的,我錯過了os.path.exists (感謝kanja,Blair和Douglas)。 這就是我現在擁有的:

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

是否有“開放”的標誌,這會自動發生?


洞察這種情況的具體情況

您在特定路徑中提供特定文件,然後從文件路徑中提取目錄。 然後在確保您擁有該目錄後,嘗試打開文件進行讀取。 要評論此代碼:

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

我們希望避免覆蓋內置函數, dir 。 此外, filepath或者fullfilepath可能是一個比filename更好的語義名稱,所以這樣寫得更好:

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

你最終的目標是打開這個文件,你最初說,寫,但你基本上是接近這個目標(基於你的代碼),這樣打開文件閱讀

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

假設開放閱讀

為什麼要為您希望在那裡並且能夠閱讀的文件創建一個目錄?

只是嘗試打開文件。

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

如果目錄或文件不存在,您將獲得一個帶有相關錯誤號的IOErrorerrno.ENOENT將指向正確的錯誤號,無論您的平台如何。 如果你願意,你可以抓住它,例如:

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

假設我們正在寫作

可能就是你想要的。

在這種情況下,我們可能沒有遇到任何競爭條件。 所以就像你一樣,但請注意,對於寫作,你需要打開w模式(或a來追加)。 使用上下文管理器打開文件也是Python的最佳實踐。

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

但是,假設我們有幾個Python進程試圖將所有數據放入同一目錄中。 然後我們可能會爭論創建目錄。 在這種情況下,最好將makedirs調用包裝在try-except塊中。

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)

相關的Python文檔建議使用EAFP編碼風格(更容易要求寬恕而不是權限) 。 這意味著代碼

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

比替代方案更好

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

文檔建議這正是因為這個問題中討論的競爭條件。 此外,正如其他人在此提到的那樣,在查詢一次而不是兩次操作系統方面存在性能優勢。 最後,在某些情況下,當開發人員知道應用程序正在運行的環境時,可能會提出有利於第二個代碼的論點 - 只有在程序為其設置私有環境的特殊情況下才能提倡這個論點。本身(以及同一程序的其他實例)。

即使在這種情況下,這也是一種不好的做法,可能會導致長時間無用的調試。 例如,我們為目錄設置權限的事實不應該讓我們為我們的目的設置適當的印象權限。 可以使用其他權限掛載父目錄。 通常,程序應該始終正常工作,程序員不應該期望一個特定的環境。


你可以使用mkpath

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

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

請注意,它也將創建祖先目錄。

它適用於Python 2和3。


使用文件I / O時,需要考慮的重要事項是

TOCTTOU(檢查時間到使用時間)

因此,使用if進行檢查然後再讀取或寫入可能會導致未處理的I / O異常。 最好的方法是:

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

使用此命令檢查並創建目錄

 if not os.path.isdir(test_img_dir):
     os.mkdir(str("./"+test_img_dir))

Python3中os.makedirs支持設置exist_ok 。 默認設置為False ,這意味著如果目標目錄已存在,將引發OSError 。 通過將exist_ok設置為True ,將忽略OSError (目錄存在)並且不會創建目錄。

os.makedirs(path,exist_ok=True)

Python2中os.makedirs不支持設置exist_ok 。 您可以在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

在Python 3.4中,您還可以使用全新的pathlib模塊

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.

如果在支持shell語言的機器上運行,為什麼不使用子進程模塊? 適用於python 2.7和python 3.6

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

應該在大多數係統上做到這一點。


如果您考慮以下因素:

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

表示存在目錄(路徑)並且是目錄。 所以對我來說這樣做是我需要的。 所以我可以確保它是文件夾(不是文件)並且存在。


從Python 3.5開始, pathlib.Path.mkdir有一個exist_ok標誌:

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

這會以遞歸方式創建目錄,如果目錄已存在,則不會引發異常。

(正如os.makedirs從python 3.2開始得到一個exists_ok標誌)。


您可以使用os.listdir

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

我個人建議您使用os.path.isdir()來測試而不是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

如果你有:

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

一個愚蠢的用戶輸入:

:: /tmp/dirname/filename.etc

...如果使用os.path.exists()測試,當您將該參數傳遞給os.makedirs()時,您最終會得到一個名為filename.etc的目錄。


我已經放下了以下內容。 但這並非完全萬無一失。

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

現在正如我所說,這並非萬無一失,因為我們有可能無法創建目錄,而另一個進程在此期間創建它。


我看到Heikki Toivonen和share的答案並想到了這種變化。

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

我看到兩個具有良好品質的答案,每個答案都有一個小缺陷,所以我會考慮它:

嘗試os.path.exists ,並考慮os.makedirs進行創建。

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

如註釋和其他地方所述,存在競爭條件 - 如果在os.path.existsos.makedirs調用之間創建目錄,則os.makedirs將失敗並出現OSError 。 不幸的是,全面捕捉OSError並繼續不是萬無一失的,因為它會忽略由於其他因素(例如權限不足,完整磁盤等)而無法創建目錄。

一種選擇是捕獲OSError並檢查嵌入的錯誤代碼(請參閱是否存在從Python的OSError獲取信息的跨平台方式 ):

import os, errno

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

或者,可能有第二個os.path.exists ,但假設另一個在第一次檢查後創建了目錄,然後在第二次檢查之前將其刪除 - 我們仍然可能被欺騙。

根據應用程序,並發操作的危險可能多於或少於文件權限等其他因素造成的危險。 在選擇實現之前,開發人員必須更多地了解正在開發的特定應用程序及其預期環境。


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

這裡的代碼使用(touch)命令

這將檢查文件是否存在,如果不存在,那麼它將創建它。





operating-system