Làm cách nào để kiểm tra xem một tệp có tồn tại mà không có ngoại lệ không?


Câu trả lời:


5154

Nếu lý do bạn đang kiểm tra là để bạn có thể làm điều gì đó như thế if file_exists: open_it(), thì an toàn hơn là sử dụng tryxung quanh nỗ lực mở nó. Kiểm tra và sau đó mở có nguy cơ tệp bị xóa hoặc di chuyển hoặc một cái gì đó giữa khi bạn kiểm tra và khi bạn cố gắng mở nó.

Nếu bạn không định mở tệp ngay lập tức, bạn có thể sử dụng os.path.isfile

Trả về Truenếu đường dẫn là một tệp thông thường hiện có. Điều này tuân theo các liên kết tượng trưng, ​​vì vậy cả islink ()isfile () đều có thể đúng với cùng một đường dẫn.

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

nếu bạn cần chắc chắn đó là một tập tin.

Bắt đầu với Python 3.4, pathlibmô-đun cung cấp một cách tiếp cận hướng đối tượng (được nhập pathlib2vào trong Python 2.7):

from pathlib import Path

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

Để kiểm tra một thư mục, hãy làm:

if my_file.is_dir():
    # directory exists

Để kiểm tra xem một Pathđối tượng có tồn tại độc lập với việc đó là tệp hoặc thư mục hay không, hãy sử dụng exists():

if my_file.exists():
    # path exists

Bạn cũng có thể sử dụng resolve(strict=True)trong một trykhối:

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

40
liên quan đến nhận xét đầu tiên (sử dụng "thử" nếu kiểm tra trước khi mở) thật không may, điều này sẽ không hoạt động nếu bạn muốn mở để nối thêm để chắc chắn rằng nó tồn tại trước khi chế độ 'a' sẽ tạo nếu không tồn tại.
makapuf

6
Lưu ý FileNotFoundErrorđã được giới thiệu trong Python 3. Nếu bạn cũng cần hỗ trợ Python 2.7 cũng như Python 3, bạn có thể sử dụng IOErrorthay thế ( FileNotFoundErrorlớp con nào) stackoverflow.com/a/21368457/1960959
scottclowe 29/03/19

7
@makapuf Bạn có thể mở nó để "cập nhật" ( open('file', 'r+')) và sau đó tìm kiếm đến cùng.
kyrill

2111

Bạn có os.path.existschức năng:

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

Điều này trả về Truecho cả tệp và thư mục nhưng thay vào đó bạn có thể sử dụng

os.path.isfile(file_path)

để kiểm tra nếu đó là một tập tin cụ thể. Nó theo symlink.


966

Không giống như isfile(), exists()sẽ trở lại Truecho các thư mục. Vì vậy, tùy thuộc vào việc bạn chỉ muốn các tệp đơn giản hoặc các thư mục, bạn sẽ sử dụng isfile()hoặc exists(). Đây là một số đầu ra REPL đơn giản:

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

623
import os.path

if os.path.isfile(filepath):

320

Sử dụng os.path.isfile()với os.access():

import os

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

60
có nhiều điều kiện, một số trong đó là thừa, ít rõ ràng và rõ ràng.
wim

10
Nó cũng là dư thừa. Nếu tập tin không tồn tại, os.access()sẽ trả về false.
Hầu tước Lorne

9
@EJP Trong các tập tin linux có thể tồn tại nhưng không thể truy cập được.
điện tử

8
vì bạn import os, bạn không cần phải làm import os.pathlại vì nó đã là một phần của os. Bạn chỉ cần nhập os.pathnếu bạn chỉ sử dụng các hàm từ os.pathvà không phải từ oschính nó, để nhập một thứ nhỏ hơn, nhưng khi bạn sử dụng os.accessos.R_OK , không cần nhập lần thứ hai.
Jester

287
import os
os.path.exists(path) # Returns whether the path (directory or file) exists or not
os.path.isfile(path) # Returns whether the file exists or not

2
Nói chung, không thực hành tốt để đặt tên biến giống như tên phương thức.
Homunculus Reticulli

245

Mặc dù hầu hết mọi cách có thể đã được liệt kê trong (ít nhất một trong số) các câu trả lời hiện có (ví dụ: cụ thể Python 3,4 đã được thêm vào), tôi sẽ cố gắng nhóm mọi thứ lại với nhau.

Lưu ý : mọi đoạn mã thư viện chuẩn Python mà tôi sắp đăng, thuộc phiên bản 3.5.3 .

Báo cáo vấn đề :

  1. Kiểm tra tệp (có thể tranh luận : cũng có thư mục (tệp "đặc biệt")?)
  2. Không sử dụng thử / trừ / khác / cuối cùng khối

Giải pháp có thể :

  1. [Python 3]: os.path. tồn tại ( đường ) (cũng kiểm tra các thành viên chức năng khác trong gia đình như os.path.isfile, os.path.isdir, os.path.lexistscho hành vi hơi khác nhau)

    os.path.exists(path)

    Trả về Truenếu đường dẫn đề cập đến một đường dẫn hiện có hoặc một mô tả tệp mở. Trả về Falsecho các liên kết tượng trưng bị hỏng. Trên một số nền tảng, chức năng này có thể trở lại Falsenếu quyền không được cấp để thực thi os.stat () trên tệp được yêu cầu, ngay cả khi đường dẫn thực sự tồn tại.

    Tất cả đều tốt, nhưng nếu theo cây nhập khẩu:

    • os.path- posixpath.py ( ntpath.py )

      • genericpath.py , dòng ~ # 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

    nó chỉ là một khối thử / ngoại trừ xung quanh [Python 3]: os. stat ( đường dẫn, *, dir_fd = Không có, follow_symlinks = True ) . Vì vậy, mã của bạn là thử / ngoại trừ miễn phí, nhưng thấp hơn trong framestack có (ít nhất) một khối như vậy. Điều này cũng áp dụng cho các chức năng khác ( bao gồm os.path.isfile ).

    1.1. [Python 3]: Đường dẫn. is_file ()

    • Đó là một cách xử lý đường dẫn fancier (và nhiều python hơn ), nhưng
    • Dưới mui xe, nó thực hiện chính xác điều tương tự ( pathlib.py , dòng ~ # 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 3]: Với Trình quản lý bối cảnh câu lệnh . Hoặc:

    • Tạo một cái:

      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 ...)
      • Và cách sử dụng của nó - Tôi sẽ sao chép os.path.isfilehành vi (lưu ý rằng đây chỉ là để thể hiện mục đích, không cố gắng viết mã như vậy cho sản xuất ):

        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
    • Sử dụng [Python 3]: bối cảnh. triệt tiêu ( * ngoại lệ ) - được thiết kế đặc biệt để loại bỏ có chọn lọc các ngoại lệ


    Tuy nhiên, họ dường như wrappers qua thử / trừ / khác / cuối cùng khối, như [Python 3]: Các với tuyên bố nêu rõ:

    Điều này cho phép thử chung ... ngoại trừ ... cuối cùng các mẫu sử dụng được gói gọn để sử dụng lại thuận tiện.

  3. Các chức năng truyền tải hệ thống tệp (và tìm kiếm kết quả cho (các) mục phù hợp)


    Vì các lần lặp này qua các thư mục, (trong hầu hết các trường hợp), chúng không hiệu quả cho vấn đề của chúng tôi (có những trường hợp ngoại lệ, như bing toàn cầu không được ký tự đại diện - như @ShadowRanger chỉ ra), vì vậy tôi sẽ không nhấn mạnh vào chúng. Chưa kể rằng trong một số trường hợp, xử lý tên tệp có thể được yêu cầu.

  4. [Python 3]: os. truy cập ( đường dẫn, chế độ, *, dir_fd = Không có, có hiệu lực = Sai, follow_symlinks = Đúng ) có hành vi gần với os.path.exists(thực ra nó rộng hơn, chủ yếu là do đối số thứ 2 )

    • Quyền Người dùng có thể hạn chế tệp "khả năng hiển thị" như tài liệu trạng thái:

      ... kiểm tra xem người dùng gọi có quyền truy cập được chỉ định vào đường dẫn hay không . Chế độ nên là F_OK để kiểm tra sự tồn tại của đường dẫn ...

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

    Kể từ khi tôi còn làm việc trong C , tôi sử dụng phương pháp này cũng bởi vì dưới mui xe, nó gọi mẹ đẻ API s (một lần nữa, thông qua "$ {} PYTHON_SRC_DIR /Modules/posixmodule.c" ), nhưng nó cũng mở ra một cánh cửa để có thể sử dụng lỗi và nó không phải là ic Python như các biến thể khác. Vì vậy, như @AaronHall đã chỉ ra một cách đúng đắn, đừng sử dụng nó trừ khi bạn biết bạn đang làm gì:

    Lưu ý : cũng có thể gọi API gốc thông qua [Python 3]: ctypes - Thư viện hàm ngoại cho Python , nhưng trong hầu hết các trường hợp, nó phức tạp hơn.

    ( Win cụ thể): Kể từ khi vcruntime * ( msvcr * ) .dll xuất khẩu một [MS.Docs]: _access, _waccess gia đình chức năng là tốt, đây là một ví dụ:

    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.notexist", os.F_OK)
    -1

    Ghi chú :

    • Mặc dù đó không phải là một cách thực hành tốt, tôi đang sử dụng os.F_OKtrong cuộc gọi, nhưng đó chỉ là sự rõ ràng (giá trị của nó là 0 )
    • Tôi đang sử dụng _waccess để cùng một mã hoạt động trên Python3Python2 (mặc dù có sự khác biệt liên quan đến unicode giữa chúng)
    • Mặc dù mục tiêu này nhắm đến một khu vực rất cụ thể, nó không được đề cập trong bất kỳ câu trả lời nào trước đó


    Bản sao Lnx ( Ubtu (16 x64) ) cũng vậy:

    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"/tmp.notexist", os.F_OK)
    -1

    Ghi chú :

    • Thay vào đó , đường dẫn của mã hóa libc ( "/lib/x86_64-linux-gnu/libc.so.6" ) có thể (và rất có thể, sẽ) khác nhau giữa các hệ thống, Không ai (hoặc chuỗi trống) có thể được chuyển đến hàm tạo CDLL ( ctypes.CDLL(None).access(b"/tmp", os.F_OK)). Theo [man7]: DLOPEN (3) :

      Nếu tên tệp là NULL, thì xử lý trả về là dành cho chương trình chính. Khi được trao cho dlsym (), tay cầm này gây ra tìm kiếm biểu tượng trong chương trình chính, theo sau là tất cả các đối tượng chia sẻ được tải khi khởi động chương trình và sau đó tất cả các đối tượng chia sẻ được tải bởi dlopen () với cờ RTLD_GLOBAL .

      • Chương trình chính (hiện tại) ( python ) được liên kết với libc , vì vậy các ký hiệu của nó (bao gồm cả quyền truy cập ) sẽ được tải
      • Điều này phải được xử lý cẩn thận, vì các chức năng như chính , Py_Main và (tất cả) các khác đều khả dụng; gọi họ có thể có tác động thảm họa (trên chương trình hiện tại)
      • Điều này cũng không áp dụng cho Win (nhưng đó không phải là vấn đề lớn, vì msvcrt.dll nằm trong "% SystemRoot% \ System32" , mặc định là % PATH% ). Tôi muốn đưa mọi thứ đi xa hơn và sao chép hành vi này trên Win (và gửi một bản vá), nhưng khi nó bật ra, [MS.Docs]: Hàm GetProcAddress chỉ "nhìn thấy" các biểu tượng được xuất , vì vậy trừ khi ai đó khai báo các hàm trong tệp thực thi chính như __declspec(dllexport)(tại sao trên trái đất, người bình thường sẽ làm điều đó?), chương trình chính có thể tải nhưng khá nhiều không sử dụng được
  5. Cài đặt một số mô-đun của bên thứ ba với khả năng hệ thống tập tin

    Nhiều khả năng, sẽ dựa vào một trong những cách trên (có thể với các tùy chỉnh nhỏ).
    Một ví dụ sẽ là (một lần nữa, Win cụ thể) [GitHub]: mhammond / pywin32 - Phần mở rộng Python cho Windows (pywin32) , là một trình bao bọc Python trên WINAPI .

    Nhưng, vì đây giống như một cách giải quyết hơn, tôi dừng lại ở đây.

  6. Một cách giải quyết khác (khập khiễng) ( gainarie ) là (như tôi muốn gọi nó), cách tiếp cận sysadmin : sử dụng Python như một trình bao bọc để thực thi các lệnh shell

    • Giành chiến thắng :

      (py35x64_test) e:\Work\Dev\StackOverflow\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\StackOverflow\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
    • Nix ( Lnx ( Ubtu )):

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

Dòng dưới cùng :

  • Đừng sử dụng các khối try / trừ / khác / cuối cùng , bởi vì chúng có thể ngăn bạn gặp phải một loạt các vấn đề khó chịu. Một ví dụ ngược lại mà tôi có thể nghĩ đến là hiệu năng: các khối như vậy rất tốn kém, vì vậy hãy cố gắng không đặt chúng vào mã mà nó phải chạy hàng trăm nghìn lần mỗi giây (nhưng vì (trong hầu hết các trường hợp) nó liên quan đến truy cập đĩa, nó sẽ không phải là trường hợp).

Lưu ý cuối cùng :

  • Tôi sẽ cố gắng cập nhật, mọi đề xuất đều được chào đón, tôi sẽ kết hợp mọi thứ hữu ích sẽ đưa ra câu trả lời

3
Bạn có thể giải thích về tuyên bố này? "Mặc dù đó không phải là một cách thực hành tốt, tôi đang sử dụng os.F_OK trong cuộc gọi, nhưng đó chỉ là sự rõ ràng (giá trị của nó là 0)"
sk8asd123

6
@ sk8asd123: Loại khó nhận xét trong một nhận xét: nói chung, tốt nhất là sử dụng hằng số với các chức năng mà chúng đi kèm. Điều đó áp dụng khi làm việc với nhiều mô-đun xác định cùng một hằng số, bởi vì một số mô-đun có thể không cập nhật và tốt nhất là các hàm và hằng số được đồng bộ hóa. Khi làm việc với ctypes (gọi các hàm trực tiếp) tôi nên xác định hằng số (từ MSDN ) hoặc không sử dụng hằng số. Đó chỉ là một hướng dẫn mà tôi sử dụng, trong 99,9% có lẽ nó không có gì khác biệt (về mặt chức năng).
CristiFati

3
@CristiFati: Kể từ 3.6, glob.iglob(và glob.globcũng vậy) dựa trênos.scandir , vì vậy bây giờ nó lười biếng; để có được lần truy cập đầu tiên trong thư mục gồm 10 triệu tệp, bạn chỉ quét cho đến khi bạn đạt được lần truy cập đầu tiên. Và ngay cả trước 3.6, nếu bạn sử dụng globcác phương thức không có bất kỳ ký tự đại diện nào, chức năng này rất thông minh: Nó biết bạn chỉ có thể có một lần truy cập, do đó, nó đơn giản hóa việc tạo hình thành chỉ os.path.isdirhoặcos.path.lexists (tùy thuộc vào việc đường dẫn kết thúc /).
ShadowRanger

3
Đó là phần thứ hai trong nhận xét của tôi (toàn cầu không có ký tự đại diện không thực sự lặp lại thư mục và không bao giờ) có nghĩa là đó là một giải pháp hiệu quả hoàn hảo cho vấn đề (chậm hơn gọi trực tiếp os.path.isdirhoặc os.path.lexistvì đó là một chuỗi các lệnh gọi và chuỗi hàm cấp Python hoạt động trước khi nó quyết định đường dẫn hiệu quả là khả thi, nhưng không có cuộc gọi hệ thống hoặc I / O bổ sung nào hoạt động, đó là các lệnh có cường độ chậm hơn).
ShadowRanger

154

Đây là cách đơn giản nhất để kiểm tra nếu một tập tin tồn tại. Chỉ tệp tồn tại khi bạn kiểm tra không đảm bảo rằng nó sẽ ở đó khi bạn cần mở nó.

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

17
Miễn là bạn có ý định truy cập tệp, điều kiện cuộc đua tồn tại , bất kể chương trình của bạn được xây dựng như thế nào. Chương trình của bạn không thể đảm bảo rằng một quy trình khác trên máy tính chưa sửa đổi tệp. Đó là những gì Eric Lippert đề cập đến như một ngoại lệ ngoại sinh . Bạn không thể tránh nó bằng cách kiểm tra sự tồn tại của tập tin trước.
Isaac Supeene

@IsaacSupeene Thực hành tốt nhất là làm cho cửa sổ của (tệp) hoạt động càng nhỏ càng tốt, sau đó là xử lý ngoại lệ thích hợp
un33k

145

Python 3.4+ có mô-đun đường dẫn hướng đối tượng: pathlib . Sử dụng mô-đun mới này, bạn có thể kiểm tra xem một tệp có tồn tại như thế này không:

import pathlib
p = pathlib.Path('path/to/file')
if p.is_file():  # or p.is_dir() to see if it is a directory
    # do stuff

Bạn có thể (và thường nên) vẫn sử dụng một try/exceptkhối khi mở tệp:

try:
    with p.open() as f:
        # do awesome stuff
except OSError:
    print('Well darn.')

Mô-đun pathlib có rất nhiều nội dung thú vị trong đó: tạo khối thuận tiện, kiểm tra chủ sở hữu tệp, tham gia đường dẫn dễ dàng hơn, v.v ... Thật đáng để kiểm tra. Nếu bạn đang dùng Python cũ (phiên bản 2.6 trở lên), bạn vẫn có thể cài đặt pathlib với pip:

# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2

Sau đó nhập nó như sau:

# Older Python versions
import pathlib2 as pathlib

124

Thích tuyên bố thử. Nó được coi là phong cách tốt hơn và tránh các điều kiện chủng tộc.

Đừng tin lời tôi. Có rất nhiều hỗ trợ cho lý thuyết này. Đây là một cặp vợ chồng:


3
Vui lòng thêm các nguồn tốt hơn để hỗ trợ tuyên bố của bạn.
BlueTrin

11
Liên kết tránh điều kiện cuộc đua (hỗ trợ apple dev) không hỗ trợ câu trả lời của bạn. Nó chỉ quan tâm đến việc sử dụng các tệp tạm thời chứa thông tin nhạy cảm trên các hệ điều hành được thiết kế kém, không chứa các tệp / thư mục tạm thời trong hộp cát thông qua các quyền hạn chế. Sử dụng try...exceptkhông giúp phân giải rằng vấn đề anyway.
jstine

Vấn đề với phương pháp này là nếu bạn có một đoạn mã quan trọng tùy thuộc vào tệp không tồn tại, việc đặt nó trong except:mệnh đề sẽ làm cho một ngoại lệ phát sinh trong phần này của mã của bạn sẽ đưa ra một thông báo khó hiểu (lỗi thứ hai được đưa ra trong quá trình việc xử lý cái đầu tiên.)
Camion

119

Làm cách nào để kiểm tra xem một tệp có tồn tại hay không, sử dụng Python mà không sử dụng câu lệnh try?

Hiện có sẵn từ Python 3.4, nhập và khởi tạo một Pathđối tượng bằng tên tệp và kiểm tra is_filephương thức (lưu ý rằng điều này trả về True cho các liên kết tượng trưng chỉ vào các tệp thông thường):

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

Nếu bạn đang dùng Python 2, bạn có thể nhập mô-đun pathlib từ pypi pathlib2hoặc kiểm tra isfiletừ os.pathmô-đun:

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

Bây giờ có lẽ là câu trả lời trực tiếp thực dụng tốt nhất ở đây, nhưng có khả năng xảy ra tình trạng chủng tộc (tùy thuộc vào những gì bạn đang cố gắng thực hiện) và thực tế là việc triển khai cơ bản sử dụng một try, nhưng Python sử dụng tryở mọi nơi trong quá trình thực hiện.

Bởi vì Python sử dụng tryở mọi nơi, thực sự không có lý do gì để tránh việc triển khai sử dụng nó.

Nhưng phần còn lại của câu trả lời này cố gắng xem xét những cảnh báo này.

Câu trả lời dài hơn, nhiều hơn

Có sẵn từ Python 3.4, sử dụng Pathđối tượng mới trong pathlib. Lưu ý rằng điều đó .existskhông hoàn toàn đúng, bởi vì các thư mục không phải là tệp (ngoại trừ theo nghĩa unix rằng mọi thứ đều là tệp).

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

Vì vậy, chúng ta cần sử dụng is_file:

>>> root.is_file()
False

Đây là sự giúp đỡ về is_file:

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

Vì vậy, hãy lấy một tệp mà chúng ta biết là một tệp:

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

Theo mặc định, NamedTemporaryFilexóa tệp khi đóng (và sẽ tự động đóng khi không còn tham chiếu nào nữa).

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

Tuy nhiên, nếu bạn đi sâu vào triển khai , bạn sẽ thấy điều đó is_filesử dụng 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

Điều kiện cuộc đua: Tại sao chúng tôi thích thử

Chúng tôi thích trybởi vì nó tránh điều kiện chủng tộc. Với try, bạn chỉ cần cố gắng đọc tệp của mình, hy vọng nó sẽ ở đó và nếu không, bạn sẽ bắt ngoại lệ và thực hiện bất kỳ hành vi dự phòng nào có ý nghĩa.

Nếu bạn muốn kiểm tra xem một tệp có tồn tại trước khi bạn cố đọc nó không, và bạn có thể đang xóa nó và sau đó bạn có thể đang sử dụng nhiều luồng hoặc quy trình, hoặc một chương trình khác biết về tệp đó và có thể xóa nó - bạn có nguy cơ một điều kiện cuộc đua nếu bạn kiểm tra nó tồn tại, bởi vì sau đó bạn đang chạy đua để mở nó trước điều kiện của nó của nó (sự tồn tại của nó) thay đổi.

Điều kiện cuộc đua rất khó để gỡ lỗi vì có một cửa sổ rất nhỏ trong đó chúng có thể khiến chương trình của bạn bị lỗi.

Nhưng nếu đây là động lực của bạn, bạn có thể nhận được giá trị của một trytuyên bố bằng cách sử dụng trình suppressquản lý bối cảnh.

Tránh các điều kiện cuộc đua mà không có một tuyên bố thử: suppress

Python 3.4 cung cấp cho chúng ta trình suppressquản lý bối cảnh (trước đây là trình ignorequản lý bối cảnh), thực hiện chính xác về mặt ngữ nghĩa trong cùng một số dòng, trong khi (ít nhất là bề ngoài) đáp ứng yêu cầu ban đầu để tránh một trytuyên bố:

from contextlib import suppress
from pathlib import Path

Sử dụng:

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

Đối với Pythons trước đó, bạn có thể tự lăn suppress, nhưng không có tryý nghĩa sẽ dài dòng hơn so với. Tôi tin rằng đây thực sự là câu trả lời duy nhất không sử dụng tryở bất kỳ cấp độ nào trong Python có thể được áp dụng cho Python 3,4 vì nó sử dụng trình quản lý bối cảnh:

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)

Có lẽ dễ dàng hơn với một thử:

from contextlib import contextmanager

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

Các tùy chọn khác không đáp ứng yêu cầu "không thử":

đồng vị

import os
os.path.isfile(path)

từ các tài liệu :

os.path.isfile(path)

Trả về True nếu đường dẫn là một tệp thông thường hiện có. Điều này tuân theo các liên kết tượng trưng, ​​vì vậy cả hai islink()isfile()có thể đúng cho cùng một đường dẫn.

Nhưng nếu bạn kiểm tra nguồn của hàm này, bạn sẽ thấy nó thực sự sử dụng câu lệnh thử:

# 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

Tất cả những gì nó đang làm là sử dụng đường dẫn đã cho để xem liệu nó có thể lấy số liệu thống kê về nó hay không, bắt OSErrorvà sau đó kiểm tra xem đó có phải là tệp không nếu nó không đưa ra ngoại lệ.

Nếu bạn có ý định làm một cái gì đó với tệp, tôi sẽ đề nghị trực tiếp thử nó với một lần thử - ngoại trừ để tránh điều kiện cuộc đua:

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

os.access

Có sẵn cho Unix và Windows os.access, nhưng để sử dụng, bạn phải truyền cờ và nó không phân biệt giữa các tệp và thư mục. Điều này được sử dụng nhiều hơn để kiểm tra xem người dùng thực sự có quyền truy cập trong môi trường đặc quyền nâng cao hay không:

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

Nó cũng bị các vấn đề điều kiện chủng tộc tương tự như isfile. Từ các tài liệu :

Lưu ý: Sử dụng access () để kiểm tra xem người dùng có được phép mở tệp hay không trước khi thực sự sử dụng open () tạo lỗ hổng bảo mật, vì người dùng có thể khai thác khoảng thời gian ngắn giữa kiểm tra và mở tệp để thao tác. Nên sử dụng các kỹ thuật EAFP. Ví dụ:

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

được viết tốt hơn là:

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

Tránh sử dụng os.access . Đây là một hàm cấp thấp có nhiều cơ hội hơn cho lỗi người dùng so với các đối tượng và hàm cấp cao hơn được thảo luận ở trên.

Chỉ trích một câu trả lời khác:

Một câu trả lời khác nói về điều này os.access:

Cá nhân, tôi thích cái này vì dưới mui xe, nó gọi API gốc (thông qua "$ {PYTHON_SRC_DIR} /Modules/poseixmodule.c"), nhưng nó cũng mở ra một cổng cho các lỗi người dùng có thể xảy ra và nó không phải là Pythonic như các biến thể khác :

Câu trả lời này cho biết họ thích một phương pháp không có lỗi Pythonic, không có lỗi. Dường như khuyến khích người dùng sử dụng API cấp thấp mà không hiểu chúng.

Nó cũng tạo ra một trình quản lý bối cảnh, bằng cách quay lại vô điều kiện True, cho phép tất cả các Ngoại lệ (bao gồm KeyboardInterruptSystemExit!) Vượt qua một cách im lặng, đó là một cách tốt để che giấu các lỗi.

Điều này dường như để khuyến khích người dùng áp dụng các thực hành kém.


87
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!"

Nhập osgiúp dễ dàng điều hướng và thực hiện các hành động tiêu chuẩn với hệ điều hành của bạn.

Để tham khảo cũng xem Làm thế nào để kiểm tra xem một tệp có tồn tại bằng Python không?

Nếu bạn cần hoạt động cấp cao, sử dụng shutil.


9
Câu trả lời này là sai. os.path.existstrả về true cho những thứ không phải là tập tin, chẳng hạn như thư mục. Điều này cho kết quả dương tính giả. Xem các câu trả lời khác mà đề nghị os.path.isfile.
Chris Johnson

84

Kiểm tra các tệp và thư mục với os.path.isfile(), os.path.isdir()os.path.exists()

Giả sử rằng "đường dẫn" là một đường dẫn hợp lệ, bảng này hiển thị những gì được trả về bởi mỗi chức năng cho các tệp và thư mục:

nhập mô tả hình ảnh ở đây

Bạn cũng có thể kiểm tra xem một tệp có phải là một loại tệp nhất định bằng cách sử dụng os.path.splitext()phần mở rộng không (nếu bạn chưa biết)

>>> import os
>>> path = "path to a word document"
>>> os.path.isfile(path)
True
>>> os.path.splitext(path)[1] == ".docx" # test if the extension is .docx
True

72

Trong năm 2016, cách tốt nhất vẫn là sử dụng os.path.isfile:

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

Hoặc trong Python 3 bạn có thể sử dụng pathlib:

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

3
Tôi có thể hỏi: lợi thế của việc sử dụng mô-đun 'pathlib' thay vì mô-đun 'os' trong python3 để kiểm tra này là gì?
Joko

3
pathliblà giải pháp OOP của python cho các đường dẫn. Bạn có thể làm nhiều hơn với nó. Nếu bạn chỉ cần kiểm tra sự tồn tại, lợi thế không quá lớn.
KaiBuxe

65

Dường như không có sự khác biệt về ý nghĩa chức năng giữa thử / ngoại trừ và isfile()vì vậy bạn nên sử dụng cái nào có ý nghĩa.

Nếu bạn muốn đọc một tập tin, nếu nó tồn tại, hãy làm

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

Nhưng nếu bạn chỉ muốn đổi tên một tệp nếu nó tồn tại và do đó không cần phải mở nó, hãy làm

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

Nếu bạn muốn ghi vào một tập tin, nếu nó không tồn tại, hãy làm

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

Nếu bạn cần khóa tập tin, đó là một vấn đề khác.


3
Câu trả lời này là sai. os.path.existstrả về true cho những thứ không phải là tập tin, chẳng hạn như thư mục. Điều này cho kết quả dương tính giả. Xem các câu trả lời khác mà đề nghị os.path.isfile.
Chris Johnson

6
Trong ví dụ thứ ba của bạn, tôi tạo một liên kết có tên filepathđúng thời gian và BAM , bạn ghi đè lên tệp đích. Bạn nên làm open(filepath, 'wx')trong một try...exceptkhối để tránh vấn đề.
quang phổ

1
Trong ví dụ thứ hai của bạn, ít nhất là trong Windows, bạn sẽ nhận được một OSErrornếu filepath + '.old'đã tồn tại: "Trên Windows, nếu dst đã tồn tại, OSError sẽ được nâng lên ngay cả khi đó là một tệp, có thể không có cách nào để thực hiện đổi tên nguyên tử khi dst đặt tên cho một tập tin hiện có. "
Tom Mydd ERICn

@TomMydd ERICn: Kể từ Python 3.3, có thểos.replace thực hiện thay thế im lặng tệp đích (nó giống hệt với os.renamehành vi Linux của nó) (nó chỉ bị lỗi nếu tên đích tồn tại và là một thư mục). Vì vậy, bạn bị mắc kẹt trên 2.x, nhưng người dùng Py3 đã có một lựa chọn tốt trong vài năm nay.
ShadowRanger

Trên renameví dụ: Nó vẫn nên được thực hiện với try/ except. os.rename(hoặc os.replacetrên Python hiện đại) là nguyên tử; làm cho nó kiểm tra sau đó đổi tên giới thiệu một cuộc đua không cần thiết và các cuộc gọi hệ thống bổ sung. Chỉ cần làmtry: os.replace(filepath, filepath + '.old') except OSError: pass
ShadowRanger

59

Bạn có thể thử điều này (an toàn hơn):

try:
    # http://effbot.org/zone/python-with-statement.htm
    # 'with' is safer to open a file
    with open('whatever.txt') as fh:
        # Do something with 'fh'
except IOError as e:
    print("({})".format(e))

Thông số sẽ là:

([Errno 2] Không có tệp hoặc thư mục như vậy: 'anything.txt')

Sau đó, tùy thuộc vào kết quả, chương trình của bạn có thể tiếp tục chạy từ đó hoặc bạn có thể mã để dừng nó nếu bạn muốn.


18
Câu hỏi ban đầu yêu cầu một giải pháp không sử dụngtry
rrs

5
Câu trả lời này bỏ lỡ quan điểm của OP. Kiểm tra là một tập tin tồn tại không giống như kiểm tra nếu bạn có thể mở nó. Sẽ có trường hợp một tập tin tồn tại nhưng vì nhiều lý do, bạn không thể mở nó.
Chris Johnson

51

Mặc dù tôi luôn khuyên bạn nên sử dụng tryexceptbáo cáo, đây là một vài khả năng cho bạn (sở thích cá nhân của tôi đang sử dụng os.access):

  1. Hãy thử mở tệp:

    Mở tệp sẽ luôn xác minh sự tồn tại của tệp. Bạn có thể tạo một chức năng giống như vậy:

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

    Nếu nó sai, nó sẽ dừng thực thi với IOError hoặc OSError chưa được xử lý trong các phiên bản sau của Python. Để bắt ngoại lệ, bạn phải sử dụng mệnh đề thử ngoại trừ. Tất nhiên, bạn luôn có thể sử dụng một trytuyên bố except` như vậy (nhờ hsandt đã làm cho tôi nghĩ rằng):

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

    Điều này sẽ kiểm tra sự tồn tại của những gì bạn chỉ định. Tuy nhiên, nó kiểm tra các tập tin thư mục vì vậy hãy cẩn thận về cách bạn sử dụng nó.

    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. Sử dụng os.access(path, mode):

    Điều này sẽ kiểm tra xem bạn có quyền truy cập vào tập tin. Nó sẽ kiểm tra quyền. Dựa trên tài liệu os.py, gõ vào os.F_OK, nó sẽ kiểm tra sự tồn tại của đường dẫn. Tuy nhiên, sử dụng điều này sẽ tạo ra một lỗ hổng bảo mật, vì ai đó có thể tấn công tệp của bạn trong khoảng thời gian giữa việc kiểm tra quyền và mở tệp. Thay vào đó, bạn nên trực tiếp mở tệp thay vì kiểm tra quyền của nó. ( EAFP vs LBYP ). Nếu bạn sẽ không mở tệp sau đó và chỉ kiểm tra sự tồn tại của nó, thì bạn có thể sử dụng tệp này.

    Dù sao, ở đây:

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

Tôi cũng nên đề cập rằng có hai cách mà bạn sẽ không thể xác minh sự tồn tại của một tệp. Vấn đề sẽ là permission deniedhoặc no such file or directory. Nếu bạn bắt được IOError, hãy đặt IOError as e(như tùy chọn đầu tiên của tôi), sau đó nhập print(e.args)để bạn có thể xác định vấn đề của mình. Tôi hy vọng nó sẽ giúp! :)


51

Ngày: 2017-12-04

Mọi giải pháp có thể đã được liệt kê trong các câu trả lời khác.

Một cách trực quan và có thể tranh luận để kiểm tra xem một tập tin có tồn tại hay không là như sau:

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

Tôi đã thực hiện một chiếc áo choàng đầy đủ để bạn tham khảo:

#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']}

37

Nếu tệp để mở, bạn có thể sử dụng một trong các kỹ thuật sau:

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

CẬP NHẬT

Chỉ để tránh nhầm lẫn và dựa trên các câu trả lời tôi nhận được, câu trả lời hiện tại tìm thấy một tệp hoặc một thư mục có tên đã cho.


9
Câu trả lời này là sai. os.path.existstrả về true cho những thứ không phải là tập tin, chẳng hạn như thư mục. Điều này cho kết quả dương tính giả. Xem các câu trả lời khác mà đề nghị os.path.isfile.
Chris Johnson

có vấn đề tích cực sai cũng có.
Zorglub29

docs.python.org/3/l Library / os.path.html # os.path.exists Để tuyên bố trên từ chris >> os.path.exists (path)> Trả về True nếu đường dẫn tham chiếu đến một đường dẫn hiện có hoặc mở mô tả tập tin. Trả về Sai cho các liên kết tượng trưng bị hỏng. Trên một số nền tảng, chức năng này có thể trả về Sai nếu không được phép thực thi os.stat () trên tệp được yêu cầu, ngay cả khi đường dẫn thực sự tồn tại. Đã thay đổi trong phiên bản 3.3: đường dẫn bây giờ có thể là một số nguyên: True được trả về nếu đó là một mô tả tệp mở, Sai thì ngược lại. Thay đổi trong phiên bản 3.6: Chấp nhận một đối tượng giống như đường dẫn.
JayRizzo

36

Ngoài ra , os.access():

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

Được R_OK, W_OKX_OKcác cờ để kiểm tra quyền ( doc ).


20
if os.path.isfile(path_to_file):
    try: 
        open(path_to_file)
            pass
    except IOError as e:
        print "Unable to open file"

Tăng các ngoại lệ được coi là một cách tiếp cận có thể chấp nhận và Pythonic, để kiểm soát dòng chảy trong chương trình của bạn. Xem xét xử lý các tệp bị thiếu với IOErrors. Trong tình huống này, một ngoại lệ IOError sẽ được nêu ra nếu tệp tồn tại nhưng người dùng không có quyền đọc.

SRC: http://www.pfinn.net/python-check-if-file-exists.html


3
OP hỏi làm thế nào để kiểm tra nếu một tập tin tồn tại. Có thể tồn tại một tập tin nhưng bạn không thể mở nó. Do đó, việc sử dụng mở tệp dưới dạng proxy để kiểm tra xem tệp có tồn tại không chính xác hay không: sẽ có phủ định sai.
Chris Johnson

19

Nếu bạn nhập khẩu NumPy đã cho các mục đích khác thì không có nhu cầu nhập khẩu các thư viện khác như pathlib, os, pathsvv

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

Điều này sẽ trả về đúng hay sai dựa trên sự tồn tại của nó.


18

Bạn có thể viết đề xuất của Brian mà không cần try:.

from contextlib import suppress

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

suppresslà một phần của Python 3.4. Trong các bản phát hành cũ hơn, bạn có thể nhanh chóng viết ra sự kìm nén của chính mình:

from contextlib import contextmanager

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

17

Tôi là tác giả của một gói đã tồn tại khoảng 10 năm và nó có chức năng giải quyết trực tiếp câu hỏi này. Về cơ bản, nếu bạn đang sử dụng hệ thống không phải Windows, nó sẽ sử dụng Popenđể truy cập find. Tuy nhiên, nếu bạn đang ở trên Windows, nó sẽ sao chép findvới một walker hệ thống tập tin hiệu quả.

Bản thân mã không sử dụng một trykhối khối trừ khi xác định hệ điều hành và do đó hướng bạn đến kiểu "Unix" findhoặc buillt tay find. Các thử nghiệm về thời gian cho thấy rằng việc tryxác định HĐH nhanh hơn, vì vậy tôi đã sử dụng một hệ thống ở đó (nhưng không ở đâu khác).

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

Và tài liệu

>>> 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']

>>>

Việc triển khai, nếu bạn quan tâm, sẽ ở đây: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190


17

Kiểm tra tập tin hoặc thư mục tồn tại

Bạn có thể làm theo ba cách sau:

Lưu ý1: Chỉ os.path.isfileđược sử dụng cho các tệp

import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists

Note2: Được os.path.existssử dụng cho cả tệp và thư mục

import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists

Các pathlib.Pathphương pháp (bao gồm trong Python 3+, có thể cài đặt với pip cho Python 2)

from pathlib import Path
Path(filename).exists()

16

Thêm một biến thể nhỏ nữa mà không được phản ánh chính xác trong các câu trả lời khác.

Điều này sẽ xử lý các trường hợp file_pathNonechuỗi hoặc rỗng.

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

Thêm một biến thể dựa trên đề xuất từ ​​Shahbaz

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

Thêm một biến thể dựa trên đề xuất từ ​​Peter Wood

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

3
if (x) return true; else return false;thực sự chỉ return x. Bốn dòng cuối cùng của bạn có thể trở thành return os.path.isfile(file_path). Trong khi chúng ta đang ở đó, toàn bộ chức năng có thể được đơn giản hóa như return file_path and os.path.isfile(file_path).
Shahbaz

Bạn phải cẩn thận return xtrong trường hợp if (x). Python sẽ xem xét một chuỗi rỗng Sai trong trường hợp chúng ta sẽ trả về một chuỗi rỗng thay vì bool. Mục đích của chức năng này là luôn trả về bool.
Marcel Wilson

1
Thật. Trong trường hợp này tuy nhiên, xos.path.isfile(..)vì vậy nó đã bool.
Shahbaz

os.path.isfile(None)đưa ra một ngoại lệ đó là lý do tại sao tôi thêm kiểm tra if. Tôi có thể chỉ cần bọc nó trong một lần thử / ngoại trừ thay vào đó nhưng tôi cảm thấy nó rõ ràng hơn theo cách này.
Marcel Wilson

3
return file_path and os.path.isfile(file_path)
Peter Wood

15

Đây là lệnh Python 1 dòng cho môi trường dòng lệnh Linux. Tôi thấy điều này RẤT TUYỆT VỜI vì tôi không phải là một anh chàng Bash nóng bỏng như vậy.

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

Tôi hy vọng điều này là hữu ích.


6
Kiểm tra một dòng trong bash: [ -f "${file}" ] && echo "file found" || echo "file not found"(giống như if [ ... ]; then ...; else ...; fi).
flotzilla

12

Bạn có thể sử dụng thư viện "HĐH" của Python:

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

5
Câu trả lời này là sai. os.path.existstrả về true cho những thứ không phải là tập tin, chẳng hạn như thư mục. Điều này cho kết quả dương tính giả. Xem các câu trả lời khác mà đề nghị os.path.isfile.
Chris Johnson

Hàm @Chris Johnson, os.path.exists () kiểm tra xem một đường dẫn có tồn tại trong hệ thống không. PATH có thể là một TRỰC TIẾP hoặc TẬP TIN. Nó sẽ hoạt động tốt trên cả hai trường hợp. Vui lòng thử với một số ví dụ
Pradip Das

Vì vậy, câu trả lời này hoạt động. Tuyệt quá. Nếu đường dẫn không phải là tệp. Đó có phải là những gì câu hỏi về? Số
Debosmit Ray

Nó phụ thuộc. Nếu mục tiêu xác định sự tồn tại của "tệp" là tìm hiểu xem đường dẫn đã tồn tại chưa (và do đó không phải là đường dẫn có thể lưu trữ dữ liệu mới mà không xóa thông tin khác), thì existsvẫn ổn. Nếu mục tiêu là xác định liệu có an toàn để mở một tệp có lẽ là hiện tại hay không, thì lời chỉ trích là hợp lý và tồn tại là không đủ chính xác. Đáng buồn thay, OP không chỉ định mục tiêu mong muốn (và có lẽ sẽ không làm như vậy nữa).
bắt đầu

12

Làm cách nào để kiểm tra xem một tệp có tồn tại mà không sử dụng câu lệnh try không?

Trong năm 2016, đây vẫn là cách dễ nhất để kiểm tra xem cả hai tệp có tồn tại hay không và đó có phải là tệp không:

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

isfilethực sự chỉ là một phương thức trợ giúp sử dụng nội bộ os.statstat.S_ISREG(mode)bên dưới. Đây os.statlà một phương pháp cấp thấp hơn sẽ cung cấp cho bạn thông tin chi tiết về các tệp, thư mục, ổ cắm, bộ đệm, v.v. Tìm hiểu thêm về os.stat tại đây

Lưu ý: Tuy nhiên, cách tiếp cận này sẽ không khóa tệp theo bất kỳ cách nào và do đó mã của bạn có thể trở nên dễ bị tổn thương do lỗi " thời gian kiểm tra đến thời gian sử dụng " ( TOCTTOU ).

Vì vậy, nâng cao các ngoại lệ được coi là một cách tiếp cận có thể chấp nhận và Pythonic, để kiểm soát dòng chảy trong chương trình của bạn. Và người ta nên xem xét xử lý các tệp bị thiếu bằng IOErrors, thay vì các ifcâu lệnh ( chỉ là một lời khuyên ).


9
import os.path

def isReadableFile(file_path, file_name):
    full_path = file_path + "/" + file_name
    try:
        if not os.path.exists(file_path):
            print "File path is invalid."
            return False
        elif not os.path.isfile(full_path):
            print "File does not exist."
            return False
        elif not os.access(full_path, os.R_OK):
            print "File cannot be read."
            return False
        else:
            print "File can be read."
            return True
    except IOError as ex:
        print "I/O error({0}): {1}".format(ex.errno, ex.strerror)
    except Error as ex:
        print "Error({0}): {1}".format(ex.errno, ex.strerror)
    return False
#------------------------------------------------------

path = "/usr/khaled/documents/puzzles"
fileName = "puzzle_1.txt"

isReadableFile(path, fileName)

@ j6m8 có, isReadableFile(path,fileName)sẽ trở lại Truenếu tệp có thể truy cập và có thể đọc được theo quy trình \ chương trình \ thread
Khaled.K
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.