python python檢查 - 如何檢查文件是否存在而沒有例外?





python找檔案 python建立資料夾 (26)


這是檢查文件是否存在的最簡單方法。 只是因為您檢查時文件存在並不能保證在您需要打開它時它就在那裡。

import os
fname = "foo.txt"
if os.path.isfile(fname):
    print("file does exist at this time")
else:
    print("no such file exists at this time")

如何在不使用try語句的情況下查看文件是否存在?




2017/12/22

雖然幾乎所有可能的方式都列在(至少有一個)現有答案中(例如添加了Python 3.4特定的東西),但我會嘗試將所有內容組合在一起。

注意 :我要發布的每個Python標準庫代碼都屬於3.5.3版(文檔引用是特定於版本3 )。

問題陳述

  1. 檢查文件( 可論證 :還是文件夾(“特殊”文件)?)存在
  2. 不要使用try / except / else / finally

可能解決方案

  1. [Python]:os.path。 existspath (還檢查其他函數族成員,如os.path.isfileos.path.isdiros.path.lexists ,略有不同的行為)

    os.path.exists(path)
    

    如果path指的是現有路徑或打開的文件描述符,則返回True 。 對於損壞的符號鏈接,返回False 。 在某些平台上,如果未授予對所請求文件執行os.stat()權限,則此函數可能返回False ,即使路徑實際存在。

    一切都很好,但是如果跟隨導入樹:

    • os.path - posixpath.pyntpath.py

      • genericpath.py ,line ~#20 +

        def exists(path):
            """Test whether a path exists.  Returns False for broken symbolic links"""
            try:
                st = os.stat(path)
            except os.error:
                return False
            return True
        

    它只是圍繞os.stat()一個try/exceptos.stat() os.stat() 。 所以,你的代碼是try/except free,但是framestack中的代碼是(至少) 一個這樣的塊。 這也適用於其他func( 包括 os.path.isfile )。

    1.1。 [Python]:pathlib.Path。 is_file ()

    • 它是處理路徑的更高級(以及更多python ic)方式, 但是
    • 在引擎蓋下,它完全相同pathlib.py ,line ~#1330 ):

      def is_file(self):
          """
          Whether this path is a regular file (also True for symlinks pointing
          to regular files).
          """
          try:
              return S_ISREG(self.stat().st_mode)
          except OSError as e:
              if e.errno not in (ENOENT, ENOTDIR):
                  raise
              # Path doesn't exist or is a broken symlink
              # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
              return False
      
  2. [Python]:使用語句上下文管理器 。 或者:

    • 創建一個:

      class Swallow:  # Dummy example
          swallowed_exceptions = (FileNotFoundError,)
      
          def __enter__(self):
              print("Entering...")
      
          def __exit__(self, exc_type, exc_value, exc_traceback):
              print("Exiting:", exc_type, exc_value, exc_traceback)
              return exc_type in Swallow.swallowed_exceptions  # only swallow FileNotFoundError (not e.g. TypeError - if the user passes a wrong argument like None or float or ...)
      
      • 它的用法 - 我將復制isfile行為(請注意,這僅用於演示目的,不要嘗試為生產編寫此類代碼):

        import os
        import stat
        
        
        def isfile_seaman(path):  # Dummy func
            result = False
            with Swallow():
                result = stat.S_ISREG(os.stat(path).st_mode)
            return result
        
    • 使用[Python]:contextlib。 suppress* exceptions - 專門用於有選擇地抑制異常


    但是,它們似乎是try/except/else/finally塊的包裝器,如[Python]: with語句指出:

    這允許常見的try ... except ... finally使用模式被封裝以便於重用。

  3. 文件系統遍歷函數(並蒐索匹配項的結果)


    由於這些迭代文件夾,(在大多數情況下)它們對我們的問題是低效的(有異常,如非通配的glob bing - 正如@ShadowRanger指出的那樣),所以我不會堅持它們。 更不用說在某些情況下,可能需要文件名處理。

  4. [Python]:os。 accesspath,mode,*,dir_fd = None,effective_ids = False,follow_symlinks = True ),其行為接近os.path.exists (實際上它更寬,主要是因為第2個參數)

    • 用戶權限可能會限製文件“可見性”,因為doc說明:

      ...測試調用用戶是否具有指定的路徑訪問權限。 模式應該是F_OK來測試路徑的存在...

    os.access("/tmp", os.F_OK)
    

    由於我也在C中工作,我也使用這種方法,因為在引擎蓋下,它調用本機API (再次,通過“$ {PYTHON_SRC_DIR} /Modules/posixmodule.c” ),但它也為可能的用戶打開了一扇門錯誤 ,它不像其他變種那樣是Python ic。 所以,正如@AaronHall正確指出的那樣,除非你知道你在做什麼,否則不要使用它:

    注意 :也可以通過[Python]調用本機API ctypes - Python的外部函數庫 ,但在大多數情況下它更複雜。

    Win特定):由於msvcr *vcruntime * )導出[MSDN]:_ access,_waccess函數係列,這裡有一個例子:

    Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\cmd.exe", os.F_OK)
    0
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\___cmd.exe", os.F_OK)
    -1
    

    備註

    • 雖然這不是一個好習慣,但我在調用中使用了os.F_OK ,但這只是為了清晰(它的值為0
    • 我正在使用_waccess因此相同的代碼適用於Python3Python2 (儘管它們之間存在unicode相關的差異)
    • 雖然這針對的是一個非常具體的領域, 但在之前的任何答案中都沒有提及


    LnxUbtu(16 x64) )對應物:

    Python 3.5.2 (default, Nov 17 2016, 17:05:23)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp", os.F_OK)
    0
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp1", os.F_OK)
    -1
    

    備註

    • 而是硬編碼libc的路徑( “/lib/x86_64-linux-gnu/libc.so.6” ),它可能(並且很可能會)在系統之間變化, None (或空字符串)可以傳遞給CDLL構造函數( ctypes.CDLL(None).access(b"/tmp", os.F_OK) )。 根據[man]:DLOPEN(3)

      如果filename為NULL,則返回的句柄用於主程序。 當給予dlsym ()時,此句柄會導致在主程序中搜索符號,然後在程序啟動時加載所有共享對象,然後由dlopen ()加載標記為RTLD_GLOBAL的所有共享對象。

      • 主(當前)程序( python )與libc鏈接,因此將加載其符號(包括access
      • 這必須小心處理,因為mainPy_Main和(所有)其他函數都可用; 打電話給他們可能會產生災難性後果(在當前的節目中)
      • 這也不適用於Win (但這並不是什麼大問題,因為msvcrt.dll位於“%SystemRoot%\ System32”中 ,默認情況下為%PATH% )。 我想更進一步並在Win上複製這種行為(並提交一個補丁),但事實證明, [MSDN]:GetProcAddress函數只“看到” 導出的符號,所以除非有人將主可執行文件中的函數聲明為__declspec(dllexport) (為什麼普通人會在地球上這樣做?),主程序是可加載的,但幾乎無法使用
  5. 使用文件系統功能安裝一些第三方模塊

    最有可能的是,將依賴於上述方法之一(可能需要輕微的自定義)。
    一個例子(再次, Win特定) [GitHub]:Python for Windows(pywin32)擴展 ,它是WINAPI上Python包裝器。

    但是,由於這更像是一種解決方法,我在這裡停下來。

  6. 另一個(跛腳)解決方法( 獲得 )是(我喜歡稱之為) sysadmin方法:使用Python作為執行shell命令的包裝器

    • 勝利

      (py35x64_test) e:\Work\Dev\\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe\" > nul 2>&1'))"
      0
      
      (py35x64_test) e:\Work\Dev\\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe.notexist\" > nul 2>&1'))"
      1
      
    • LnxUbtu ):

      [[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp\" > /dev/null 2>&1'))"
      0
      [[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp.notexist\" > /dev/null 2>&1'))"
      512
      

底線

  • 使用try / except / else / finally塊,因為它們可以防止你遇到一系列令人討厭的問題。 我能想到的一個反例是性能:這樣的塊是昂貴的,所以盡量不要將它們放在它應該每秒運行數十萬次的代碼中(但是因為(在大多數情況下)它涉及磁盤訪問,事實並非如此)。

最後的說明

  • 我將盡力保持最新,歡迎提出任何建議,我會將有用的任何內容納入到答案中



我是一個已經存在了大約10年的軟件包的作者,它有一個直接解決這個問題的功能。基本上,如果您使用的是非Windows系統,則用於Popen訪問find。但是,如果您使用的是Windows,則會find使用高效的文件系統walker進行複制。

代碼本身不使用try塊...除了確定操作系統,從而引導您進入“Unix”風格find或手動風格find。時間測試表明,try確定操作系統的速度更快,所以我確實在那裡使用了一個(但沒有其他地方)。

>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']

而且文件......

>>> print pox.find.__doc__
find(patterns[,root,recurse,type]); Get path to a file or directory

    patterns: name or partial name string of items to search for
    root: path string of top-level directory to search
    recurse: if True, recurse down from root directory
    type: item filter; one of {None, file, dir, link, socket, block, char}
    verbose: if True, be a little verbose about the search

    On some OS, recursion can be specified by recursion depth (an integer).
    patterns can be specified with basic pattern matching. Additionally,
    multiple patterns can be specified by splitting patterns with a ';'
    For example:
        >>> find('pox*', root='..')
        ['/Users/foo/pox/pox', '/Users/foo/pox/scripts/pox_launcher.py']

        >>> find('*shutils*;*init*')
        ['/Users/foo/pox/pox/shutils.py', '/Users/foo/pox/pox/__init__.py']

>>>

如果你願意,可以在這裡實現:https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190




import os.path

if os.path.isfile(filepath):



如果導入與NumPy已經用於其它用途,則沒有必要導入其他庫,例如pathlibospaths等。

import numpy as np
np.DataSource().exists("path/to/your/file")

這將根據其存在返回true或false。




2016年最好的方法仍然是使用os.path.isfile

>>> os.path.isfile('/path/to/some/file.txt')

或者在Python 3中,您可以使用pathlib

import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
    ...



import os
#Your path here e.g. "C:\Program Files\text.txt"
#For access purposes: "C:\\Program Files\\text.txt"
if os.path.exists("C:\..."):   
    print "File found!"
else:
    print "File not found!"

導入os可以更輕鬆地使用您的操作系統進行導航和執行標準操作。

有關參考,請參閱share

如果需要高級操作,請使用shutil




如何在不使用try語句的情況下使用Python檢查文件是否存在?

從Python 3.4開始,現在可以使用文件名導入和實例化Path對象,並檢查is_file方法(請注意,對於指向常規文件的符號鏈接,這將返回True):

>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False

如果您使用的是Python 2,則可以從pypi, pathlib2向後端口傳遞pathlib模塊,或者從os.path模塊檢查isfile

>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False

現在上面可能是這裡最好的實用直接答案,但是存在競爭條件的可能性(取決於你想要完成的事情),以及底層實現使用try的事實,但Python在其中使用try實現。

因為Python在任何地方都使用try ,所以沒有理由避免使用它的實現。

但是這個答案的其餘部分試圖考慮這些警告。

更長,更迂腐的答案

自Python 3.4起可用,在pathlib使用新的Path對象。 請注意.exists不太正確,因為目錄不是文件(在unix意義上除了一切都是文件)。

>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True

所以我們需要使用is_file

>>> root.is_file()
False

這是is_file的幫助:

is_file(self)
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).

所以讓我們得到一個文件,我們知道它是一個文件:

>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True

默認情況下, NamedTemporaryFile在關閉時刪除文件(並且當不存在更多引用時將自動關閉)。

>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False

但是,如果你深入研究實現 ,你會發現is_file使用了try

def is_file(self):
    """
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).
    """
    try:
        return S_ISREG(self.stat().st_mode)
    except OSError as e:
        if e.errno not in (ENOENT, ENOTDIR):
            raise
        # Path doesn't exist or is a broken symlink
        # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
        return False

比賽條件:為什麼我們喜歡嘗試

我們喜歡try因為它避免了競爭條件。 通過try ,您只需嘗試讀取您的文件,期望它在那裡,如果沒有,您將捕獲異常並執行任何有意義的回退行為。

如果要在嘗試讀取文件之前檢查文件是否存在,並且可能正在刪除它,然後您可能正在使用多個線程或進程,或者其他程序知道該文件並且可能刪除它 - 您冒險一個競爭條件,如果你檢查它存在,因為你然後競爭在它的條件 (它的存在)改變之前打開它。

競爭條件很難調試,因為它有一個非常小的窗口,它可能導致程序失敗。

但如果這是你的動機,你可以使用suppress上下文管理器獲取try語句的值。

沒有try語句避免競爭條件: suppress

Python 3.4為我們提供了suppress上下文管理器(以前稱為ignore上下文管理器),它在語義上在更少的行中完全相同,同時(至少表面上)滿足原始的請求以避免try語句:

from contextlib import suppress
from pathlib import Path

用法:

>>> with suppress(OSError), Path('doesnotexist').open() as f:
...     for line in f:
...         print(line)
... 
>>>
>>> with suppress(OSError):
...     Path('doesnotexist').unlink()
... 
>>> 

對於早期的Pythons,你可以滾動自己的suppress ,但不經過try將比使用更加冗長。 我相信這實際上是唯一沒有在Python中可以應用於Python之前的任何級別使用try答案,因為它使用了上下文管理器:

class suppress(object):
    def __init__(self, *exceptions):
        self.exceptions = exceptions
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is not None:
            return issubclass(exc_type, self.exceptions)

嘗試可能更容易:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass

其他選項不符合“不試”的要求:

ISFILE

import os
os.path.isfile(path)

來自docs

os.path.isfile(path)

如果path是現有常規文件,則返回True。 這遵循符號鏈接,因此對於相同的路徑, islink()isfile()都可以為true。

但是如果你檢查這個函數的source ,你會發現它確實使用了一個try語句:

# This follows symbolic links, so both islink() and isdir() can be true
# for the same path on systems that support symlinks
def isfile(path):
    """Test whether a path is a regular file"""
    try:
        st = os.stat(path)
    except os.error:
        return False
    return stat.S_ISREG(st.st_mode)
>>> OSError is os.error
True

所有它正在使用給定的路徑來查看它是否可以獲取它的統計信息,捕獲OSError ,然後檢查它是否是一個文件,如果它沒有引發異常。

如果您打算對該文件執行某些操作,我建議您嘗試直接嘗試它 - 除了避免競爭條件:

try:
    with open(path) as f:
        f.read()
except OSError:
    pass

os.access

可用於Unix和Windows的是os.access ,但要使用你必須傳遞標誌,它不區分文件和目錄。 這更多用於測試真正的調用用戶是否在提升的權限環境中具有訪問權限:

import os
os.access(path, os.F_OK)

它也遇到與isfile相同的競爭條件問題。 來自docs

注意:使用access()檢查用戶是否有權使用open()實際執行此操作之前打開文件會產生安全漏洞,因為用戶可能會利用檢查和打開文件之間的短時間間隔來操作它。 最好使用EAFP技術。 例如:

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()
return "some default data"

寫得更好:

try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCES:
        return "some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()

避免使用os.access 。 它是一個低級函數,比上面討論的更高級別的對象和函數有更多的用戶錯誤機會。

對另一個答案的批評:

另一個答案是關於os.access

就個人而言,我更喜歡這個,因為在引擎蓋下,它調用本機API(通過“$ {PYTHON_SRC_DIR} /Modules/posixmodule.c”),但它也為可能的用戶錯誤打開了一個門,它不像其他變體那樣像Pythonic :

這個答案說它更喜歡非Pythonic,容易出錯的方法,沒有任何理由。 它似乎鼓勵用戶在不了解它們的情況下使用低級API。

它還創建了一個上下文管理器,通過無條件返回True ,允許所有異常(包括KeyboardInterruptSystemExit !)以靜默方式傳遞,這是隱藏錯誤的好方法。

這似乎鼓勵用戶採用不良做法。







另外,os.access()

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()

存在R_OKW_OK以及X_OK用於測試權限的標誌(doc)。




沒有這個,你可以寫Brian的建議try:

from contextlib import suppress

with suppress(IOError), open('filename'):
    process()

suppress是Python 3.4的一部分。在舊版本中,您可以快速編寫自己的抑制:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass



os.path.isfile()os.access()

import os
import os.path

PATH='./file.txt'

if os.path.isfile(PATH) and os.access(PATH, os.R_OK):
    print "File exists and is readable"
else:
    print "Either the file is missing or not readable"



似乎try / except和isfile()之間沒有明顯的功能差異,所以你應該使用哪一個有意義。

如果要讀取文件,如果存在,請執行

try:
    f = open(filepath)
except IOError:
    print 'Oh dear.'

但是如果你只是想重命名一個文件,如果它存在,因此不需要打開它,那就行了

if os.path.isfile(filepath):
    os.rename(filepath, filepath + '.old')

如果要寫入文件,如果它不存在,請執行

# python 2
if not os.path.isfile(filepath):
    f = open(filepath, 'w')

# python 3, x opens for exclusive creation, failing if the file already exists
try:
    f = open(filepath, 'wx')
except IOError:
    print 'file already exists'

如果你需要文件鎖定,那是另一回事。




如果文件用於打開,您可以使用以下技術之一:

>>> with open('somefile', 'xt') as f: #Using the x-flag, Python3.3 and above
...     f.write('Hello\n')

>>> if not os.path.exists('somefile'): 
...     with open('somefile', 'wt') as f:
...         f.write("Hello\n")
... else:
...     print('File already exists!')

UPDATE

為了避免混淆並根據我得到的答案,當前答案找到一個文件具有給定名稱的目錄。




這是Linux命令行環境的1行Python命令。我發現這非常好,因為我不是那麼熱的Bash傢伙。

python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"

我希望這是有幫助的。




雖然我總是建議使用tryexcept聲明,但這裡有一些可能性(我個人最喜歡使用os.access):

  1. 嘗試打開文件:

    打開文件將始終驗證文件是否存在。你可以像這樣製作一個函數:

    def File_Existence(filepath):
        f = open(filepath)
        return True
    

    如果它為False,它將在更高版本的Python中以無錯的IOError或OSError停止執行。要捕獲異常,必須使用try except子句。當然,你可以隨時使用tryexcept`語句(感謝hsandt讓我思考):

    def File_Existence(filepath):
        try:
            f = open(filepath)
        except IOError, OSError: # Note OSError is for later versions of Python
            return False
    
        return True
    
  2. 使用os.path.exists(path)

    這將檢查您指定的內容的存在。但是,它會檢查文件目錄,因此請注意您如何使用它。

    import os.path
    >>> os.path.exists("this/is/a/directory")
    True
    >>> os.path.exists("this/is/a/file.txt")
    True
    >>> os.path.exists("not/a/directory")
    False
    
  3. 使用os.access(path, mode)

    這將檢查您是否有權訪問該文件。它將檢查權限。根據os.py文檔輸入os.F_OK,它將檢查路徑是否存在。但是,使用此方法會創建一個安全漏洞,因為有人可以使用檢查權限和打開文件之間的時間來攻擊您的文件。您應該直接打開文件而不是檢查其權限。(EAFPLBYP)。如果您之後不打算打開文件,只檢查其存在,那麼您可以使用它。

    無論如何,這裡:

    >>> import os
    >>> os.access("/is/a/file.txt", os.F_OK)
    True
    

我還要提一下,有兩種方法可以驗證文件是否存在。問題將是permission deniedno such file or directory。如果你抓到了IOError,請設置IOError as e(就像我的第一個選項),然後輸入print(e.args)以便您可以確定您的問題。我希望它有所幫助! :)




日期:2017年12月4日

其他答案中列出了每種可能的解決方案。

檢查文件是否存在的直觀且有爭議的方法如下:

import os
os.path.isfile('~/file.md')    # Returns True if exists, else False
additionaly check a dir
os.path.isdir('~/folder') # Returns True if the folder exists, else False
check either a dir or a file
os.path.exists('~/file')

我做了一個詳盡的備忘單供你參考:

#os.path methods in exhaustive cheatsheet
{'definition': ['dirname',
               'basename',
               'abspath',
               'relpath',
               'commonpath',
               'normpath',
               'realpath'],
'operation': ['split', 'splitdrive', 'splitext',
               'join', 'normcase'],
'compare': ['samefile', 'sameopenfile', 'samestat'],
'condition': ['isdir',
              'isfile',
              'exists',
              'lexists'
              'islink',
              'isabs',
              'ismount',],
 'expand': ['expanduser',
            'expandvars'],
 'stat': ['getatime', 'getctime', 'getmtime',
          'getsize']}



isfile()不同, exists()將為目錄返回True
因此,根據您是否只需要普通文件或目錄,您將使用isfile()exists() 。 這是一個簡單的REPL輸出。

>>> print os.path.isfile("/etc/password.txt")
True
>>> print os.path.isfile("/etc")
False
>>> print os.path.isfile("/does/not/exist")
False
>>> print os.path.exists("/etc/password.txt")
True
>>> print os.path.exists("/etc")
True
>>> print os.path.exists("/does/not/exist")
False



添加一個更微小的變化,這在其他答案中沒有完全反映出來。

這將處理file_path存在None或空字符串的情況。

def file_exists(file_path):
    if not file_path:
        return False
    elif not os.path.isfile(file_path):
        return False
    else:
        return True

根據Shahbaz的建議添加變體

def file_exists(file_path):
    if not file_path:
        return False
    else:
        return os.path.isfile(file_path)

根據Peter Wood的建議添加變體

def file_exists(file_path):
    return file_path and os.path.isfile(file_path):



你有os.path.exists函數:

import os.path
os.path.exists(file_path)

這會為文件和目錄返回True ,但您可以改為使用

os.path.isfile(file_path)

測試它是否是一個特定的文件。 它遵循符號鏈接。




您可以使用Python的“OS”庫:

>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt") 
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False



在Python 3.4中,該語言提供了一個管理文件的新模塊:

import pathlib
path = pathlib.Path('path/to/file')
if path.is_file(): # If you want to check a directory: path.is_dir()
    # If it is true, return true on your code.



如何在不使用try語句的情況下檢查文件是否存在?

在2016年,這仍然是檢查文件是否存在以及文件是否是文件的最簡單方法:

import os
os.path.isfile('./file.txt')    # Returns True if exists, else False

isfile實際上只是一個內部使用os.statstat.S_ISREG(mode)下面的輔助方法。這os.stat是一個較低級別的方法,它將為您提供有關文件,目錄,套接字,緩衝區等的詳細信息。更多關於os.stat的信息

注意:但是,此方法不會以任何方式鎖定文件,因此您的代碼可能容易受到“ 檢查使用時間 ”(TOCTTOU)錯誤的影響。

因此,提高異常被認為是一種可接受的Pythonic方法,用於程序中的流量控制。並且應該考慮使用IOErrors處理丟失的文件,而不是if語句(只是一個建議)。




如果你正在檢查的原因是你可以做一些像if file_exists: open_it()那樣的事情,那麼嘗試打開它會更安全。 檢查然後打開風險,刪除或移動文件或檢查時以及嘗試打開文件時。

如果您不打算立即打開文件,可以使用os.path.isfile

如果path是現有常規文件,則返回True 。 這遵循符號鏈接,因此對於相同的路徑, islink()os.path.isfile都可以為true。

import os.path
os.path.isfile(fname) 

如果你需要確定它是一個文件。

從Python 3.4開始, pathlib模塊提供了一種面向對象的方法(在Python 2.7中向後移植到pathlib2 ):

from pathlib import Path

my_file = Path("/path/to/file")
if my_file.is_file():
    # file exists

要檢查目錄,請執行以下操作:

if my_file.is_dir():
    # directory exists

要檢查Path對像是否存在,無論它是文件還是目錄,請使用exists()

if my_file.exists():
    # path exists

您還可以在try塊中使用resolve()

try:
    my_abs_path = my_file.resolve()
except FileNotFoundError:
    # doesn't exist
else:
    # exists






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

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

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





python file file-exists