Jawaban:
Jika alasan Anda mengecek adalah agar Anda dapat melakukan sesuatu seperti if file_exists: open_it(), lebih aman menggunakan upaya trysekitar untuk membukanya. Memeriksa dan kemudian membuka risiko file dihapus atau dipindahkan atau ada sesuatu antara ketika Anda memeriksa dan ketika Anda mencoba untuk membukanya.
Jika Anda tidak berencana untuk segera membuka file, Anda dapat menggunakannya os.path.isfile
Kembali
Truejika path adalah file biasa yang sudah ada. Ini mengikuti tautan simbolik, sehingga islink () dan isfile () bisa benar untuk jalur yang sama.
import os.path
os.path.isfile(fname)
jika Anda perlu memastikan itu adalah file.
Dimulai dengan Python 3.4, pathlibmodul ini menawarkan pendekatan berorientasi objek (backported ke pathlib2dalam Python 2.7):
from pathlib import Path
my_file = Path("/path/to/file")
if my_file.is_file():
# file exists
Untuk memeriksa direktori, lakukan:
if my_file.is_dir():
# directory exists
Untuk memeriksa apakah suatu Pathobjek ada secara independen dari apakah itu file atau direktori, gunakan exists():
if my_file.exists():
# path exists
Anda juga dapat menggunakan resolve(strict=True)di tryblok:
try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
FileNotFoundErrordiperkenalkan di Python 3. Jika Anda juga perlu mendukung Python 2.7 dan juga Python 3, Anda dapat menggunakan IOErrorsebagai gantinya ( FileNotFoundErrorsubkelas mana ) stackoverflow.com/a/21368457/1960959
open('file', 'r+')) dan kemudian mencari sampai akhir.
Anda memiliki os.path.existsfungsi:
import os.path
os.path.exists(file_path)
Ini mengembalikan Truefile dan direktori tetapi Anda bisa menggunakannya
os.path.isfile(file_path)
untuk menguji apakah itu file khusus. Ini mengikuti symlink.
Berbeda isfile(), exists()akan kembali Trueuntuk direktori. Jadi tergantung pada apakah Anda hanya menginginkan file biasa atau juga direktori, Anda akan menggunakan isfile()atau exists(). Berikut adalah beberapa output REPL sederhana:
>>> 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
Gunakan os.path.isfile()dengan 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")
os.access()akan mengembalikan false.
import os, Anda tidak perlu import os.pathlagi karena sudah menjadi bagian dari os. Anda hanya perlu mengimpor os.pathjika Anda hanya akan menggunakan fungsi dari os.pathdan bukan dari ositu sendiri, untuk mengimpor hal yang lebih kecil, tetapi saat Anda menggunakan os.accessdan os.R_OK, impor kedua tidak diperlukan.
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
Meskipun hampir setiap cara yang mungkin telah terdaftar di (setidaknya satu dari) jawaban yang ada (misalnya, hal-hal spesifik Python ditambahkan), saya akan mencoba untuk mengelompokkan semuanya menjadi satu.
Catatan : setiap bagian dari kode pustaka standar Python yang akan saya posting, milik versi 3.5.3 .
Pernyataan masalah :
Kemungkinan solusi :
[Python 3]: os.path. exists ( path ) (juga memeriksa anggota fungsi keluarga lain seperti os.path.isfile, os.path.isdir, os.path.lexistsuntuk perilaku yang sedikit berbeda)
os.path.exists(path)
Kembali
Truejika jalur merujuk ke jalur yang ada atau deskriptor file terbuka. PengembalianFalseuntuk tautan simbolis yang rusak. Pada beberapa platform, fungsi ini dapat kembaliFalsejika izin tidak diberikan untuk mengeksekusi os.stat () pada file yang diminta, bahkan jika path ada secara fisik.
Semua baik, tetapi jika mengikuti pohon impor:
os.path- posixpath.py ( ntpath.py )
genericpath.py , baris ~ # 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 Trueitu hanya blok coba / kecuali sekitar [Python 3]: os. stat ( path, *, dir_fd = Tidak Ada, follow_symlinks = Benar ) . Jadi, kode Anda dicoba / kecuali gratis, tetapi lebih rendah di framestack ada (setidaknya) satu blok tersebut. Ini juga berlaku untuk fungsi lainnya ( termasuk os.path.isfile ).
1.1. [Python 3]: Path. is_file ()
Di bawah tenda, ia melakukan hal yang persis sama ( 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[Python 3]: Dengan Manajer Konteks Pernyataan . Antara:
Buat satu:
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 ...)
Dan penggunaannya - Saya akan meniru os.path.isfileperilaku (catatan bahwa ini hanya untuk menunjukkan tujuan, jangan tidak mencoba untuk menulis kode tersebut untuk produksi ):
import os
import stat
def isfile_seaman(path): # Dummy func
result = False
with Swallow():
result = stat.S_ISREG(os.stat(path).st_mode)
return resultGunakan [Python 3]: contextlib. suppress ( * exceptionions ) - yang secara khusus dirancang untuk pengecualian penekan selektif
Tapi, mereka tampaknya menjadi pembungkus try / kecuali / else / akhirnya blok, seperti [Python 3]: Pernyataan with menyatakan:
Ini memungkinkan percobaan umum ... kecuali ... akhirnya pola penggunaan dienkapsulasi untuk penggunaan kembali yang nyaman.
Fungsi traversal sistem file (dan cari hasil untuk item yang cocok)
[Python 3]: os. listdir ( path = '.' ) (atau [Python 3]: os. scandir ( path = '.' ) pada Python v 3.5 +, backport: [PyPI]: scandir )
Di bawah tenda, keduanya menggunakan:
via [GitHub]: python / cpython - (master) cpython / Modul / posixmodule.c
Menggunakan scandir () sebagai ganti listdir () dapat secara signifikan meningkatkan kinerja kode yang juga memerlukan tipe file atau informasi atribut file, karena objek os.DirEntry memaparkan informasi ini jika sistem operasi menyediakannya ketika memindai direktori. Semua metode os.DirEntry dapat melakukan panggilan sistem, tetapi is_dir () dan is_file () biasanya hanya memerlukan panggilan sistem untuk tautan simbolik; os.DirEntry.stat () selalu memerlukan panggilan sistem di Unix tetapi hanya membutuhkan satu untuk tautan simbolis pada Windows.
os.listdir( os.scandirbila tersedia)glob.glob)
os.listdir
Karena ini beralih ke folder, (dalam sebagian besar kasus) mereka tidak efisien untuk masalah kita (ada pengecualian, seperti glob bing non wildcarded - seperti yang ditunjukkan @ShadowRanger), jadi saya tidak akan memaksa mereka. Belum lagi bahwa dalam beberapa kasus, pemrosesan nama file mungkin diperlukan.
[Python 3]: os. akses ( jalan, modus, *, dir_fd = None, effective_ids = False, follow_symlinks = True ) yang perilakunya dekat os.path.exists(sebenarnya itu lebih luas, terutama karena 2 nd argumen)
... uji apakah pengguna yang memohon memiliki akses ke jalur yang ditentukan . mode harus F_OK untuk menguji keberadaan jalur ...
os.access("/tmp", os.F_OK)
Karena saya juga bekerja di C , saya menggunakan metode ini juga karena di bawah tenda, itu panggilan asli API s (sekali lagi, melalui "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c" ), tetapi juga membuka pintu untuk kemungkinan pengguna kesalahan , dan itu bukan sebagai Python ic seperti varian lainnya. Jadi, seperti yang ditunjukkan @AaronHall dengan benar, jangan gunakan kecuali Anda tahu apa yang Anda lakukan:
Catatan : memanggil API asli juga dimungkinkan melalui [Python 3]: ctypes - Pustaka fungsi asing untuk Python , tetapi dalam kebanyakan kasus itu lebih rumit.
( Menang spesifik): Karena vcruntime * ( msvcr * ) .dll mengekspor [MS.Doc]: _access, keluarga fungsi _waccess juga, berikut ini contohnya:
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
Catatan :
os.F_OKpanggilan, tapi itu hanya untuk kejelasan (nilainya 0 )
The lnx ( Ubtu (16 x64) ) rekan juga:
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
Catatan :
Alih-alih jalur libc hardcoding ( "/lib/x86_64-linux-gnu/libc.so.6" ) yang dapat (dan kemungkinan besar, akan) bervariasi di seluruh sistem, Tidak ada (atau string kosong) dapat diteruskan ke konstruktor CDLL ( ctypes.CDLL(None).access(b"/tmp", os.F_OK)). Menurut [man7]: DLOPEN (3) :
Jika nama file NULL, maka pegangan yang dikembalikan adalah untuk program utama. Ketika diberikan ke dlsym (), gagang ini menyebabkan pencarian simbol di program utama, diikuti oleh semua objek bersama yang dimuat saat startup program, dan kemudian semua objek bersama yang dimuat oleh dlopen () dengan bendera RTLD_GLOBAL .
__declspec(dllexport)(mengapa di bumi orang biasa akan melakukan itu?), program utama dapat dimuat tetapi cukup banyak tidak dapat digunakanInstal beberapa modul pihak ketiga dengan kemampuan sistem file
Kemungkinan besar, akan bergantung pada salah satu cara di atas (mungkin dengan sedikit penyesuaian).
Salah satu contoh akan menjadi (lagi, Win spesifik) [GitHub]: mhammond / pywin32 - Python for Windows (pywin32) Extensions , yang merupakan pembungkus Python atas WINAPI .
Tapi, karena ini lebih seperti solusi, saya berhenti di sini.
Solusi (lumpuh) lain ( gainarie ) adalah (seperti saya suka menyebutnya,) pendekatan sysadmin : gunakan Python sebagai pembungkus untuk mengeksekusi perintah shell
Menangkan :
(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
Intinya :
Catatan akhir :
glob.iglob(dan glob.globjuga) didasarkan padaos.scandir , jadi sekarang malas; untuk mendapatkan hit pertama dalam direktori file 10M, Anda hanya memindai sampai mencapai hit pertama. Dan bahkan pra-3.6, jika Anda menggunakan globmetode tanpa o wildcard, fungsinya cerdas: Ia tahu Anda hanya dapat memiliki satu hit, sehingga menyederhanakan globbing menjadi adil os.path.isdiratauos.path.lexists (tergantung pada apakah path berakhir /).
os.path.isdiratau os.path.lexistkarena itu adalah sekelompok panggilan fungsi level Python dan string operasi sebelum memutuskan jalur efisien dapat dijalankan, tetapi tidak ada pemanggilan sistem tambahan atau kerja I / O, yang urutannya lebih lambat).
Ini adalah cara paling sederhana untuk memeriksa apakah ada file. Hanya karena file itu ada ketika Anda memeriksa tidak menjamin bahwa itu akan ada di sana ketika Anda perlu membukanya.
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")
Python 3.4+ memiliki modul path berorientasi objek: pathlib . Menggunakan modul baru ini, Anda dapat memeriksa apakah ada file seperti ini:
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
Anda dapat (dan biasanya seharusnya) masih menggunakan try/exceptblok ketika membuka file:
try:
with p.open() as f:
# do awesome stuff
except OSError:
print('Well darn.')
Modul pathlib memiliki banyak hal keren di dalamnya: globbing yang nyaman, memeriksa pemilik file, bergabung dengan jalur yang lebih mudah, dll. Perlu dicoba. Jika Anda menggunakan Python yang lebih lama (versi 2.6 atau yang lebih baru), Anda masih dapat menginstal pathlib dengan pip:
# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2
Kemudian impor sebagai berikut:
# Older Python versions
import pathlib2 as pathlib
Lebih suka pernyataan coba. Itu dianggap gaya yang lebih baik dan menghindari kondisi balapan.
Jangan mengambil kata saya untuk itu. Ada banyak dukungan untuk teori ini. Inilah pasangan:
try...excepttidak membantu menyelesaikan bahwa masalah pula.
except:klausa akan membuat pengecualian yang muncul di bagian kode Anda ini akan menimbulkan pesan yang membingungkan (kesalahan kedua muncul selama pemrosesan yang pertama.)
Bagaimana cara memeriksa apakah ada file, menggunakan Python, tanpa menggunakan pernyataan coba-coba?
Sekarang tersedia sejak Python 3.4, impor dan instantiate Pathobjek dengan nama file, dan periksa is_filemetode (perhatikan bahwa ini mengembalikan True untuk symlink yang menunjuk ke file biasa juga):
>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False
Jika Anda menggunakan Python 2, Anda bisa backport modul pathlib dari pypi pathlib2,, atau periksa isfiledari os.pathmodul:
>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False
Sekarang jawaban di atas mungkin merupakan jawaban langsung pragmatis terbaik di sini, tetapi ada kemungkinan kondisi ras (tergantung pada apa yang ingin Anda capai), dan fakta bahwa implementasi yang mendasarinya menggunakan a try, tetapi Python menggunakan trydi mana-mana dalam implementasinya.
Karena Python menggunakan di trymana-mana, benar-benar tidak ada alasan untuk menghindari implementasi yang menggunakannya.
Tetapi sisa dari jawaban ini mencoba untuk mempertimbangkan peringatan ini.
Tersedia sejak Python 3.4, gunakan Pathobjek baru di pathlib. Catatan yang .existstidak tepat, karena direktori bukan file (kecuali dalam arti unix bahwa semuanya adalah file).
>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True
Jadi kita perlu menggunakan is_file:
>>> root.is_file()
False
Inilah bantuan untuk is_file:
is_file(self)
Whether this path is a regular file (also True for symlinks pointing
to regular files).
Jadi mari kita dapatkan file yang kita tahu adalah file:
>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True
Secara default, NamedTemporaryFilemenghapus file ketika ditutup (dan secara otomatis akan menutup ketika tidak ada lagi referensi).
>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False
Jika Anda menggali implementasi , Anda akan melihat bahwa is_filemenggunakan 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
Kami suka trykarena itu menghindari kondisi balapan. Dengan try, Anda hanya mencoba membaca file Anda, berharap ada di sana, dan jika tidak, Anda menangkap pengecualian dan melakukan apa pun perilaku mundur yang masuk akal.
Jika Anda ingin memeriksa apakah ada file sebelum Anda mencoba untuk membacanya, dan Anda mungkin menghapusnya dan kemudian Anda mungkin menggunakan beberapa utas atau proses, atau program lain tahu tentang file itu dan dapat menghapusnya - Anda berisiko terkena suatu kondisi lomba jika Anda memeriksa itu ada, karena Anda kemudian berlomba untuk membukanya sebelum nya kondisi (keberadaannya) berubah.
Kondisi ras sangat sulit untuk di-debug karena ada jendela yang sangat kecil di mana mereka dapat menyebabkan program Anda gagal.
Tetapi jika ini adalah motivasi Anda, Anda bisa mendapatkan nilai trypernyataan dengan menggunakan suppressmanajer konteks.
suppressPython 3.4 memberi kita suppressmanajer konteks (sebelumnya ignoremanajer konteks), yang melakukan hal yang sama persis secara semantik dalam lebih sedikit baris, sementara juga (setidaknya secara dangkal) memenuhi yang asli meminta untuk menghindari trypernyataan:
from contextlib import suppress
from pathlib import Path
Pemakaian:
>>> with suppress(OSError), Path('doesnotexist').open() as f:
... for line in f:
... print(line)
...
>>>
>>> with suppress(OSError):
... Path('doesnotexist').unlink()
...
>>>
Untuk Python sebelumnya, Anda bisa menggulung sendiri suppress, tetapi tanpa trywasiat akan lebih bertele-tele daripada dengan. Saya percaya ini sebenarnya adalah satu-satunya jawaban yang tidak digunakan trypada level apa pun dalam Python yang dapat diterapkan sebelum Python 3.4 karena ia menggunakan manajer konteks sebagai gantinya:
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)
Mungkin lebih mudah dengan mencoba:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
isfile
import os
os.path.isfile(path)
dari dokumen :
os.path.isfile(path)Return True jika path adalah file biasa yang sudah ada. Ini mengikuti tautan simbolik, sehingga keduanya
islink()danisfile()bisa benar untuk jalur yang sama.
Tetapi jika Anda memeriksa sumber fungsi ini, Anda akan melihatnya benar-benar menggunakan pernyataan coba:
# 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
Semua yang dilakukannya adalah menggunakan jalur yang diberikan untuk melihat apakah bisa mendapatkan statistik, menangkap OSErrordan kemudian memeriksa apakah itu file jika tidak memunculkan pengecualian.
Jika Anda berniat melakukan sesuatu dengan file tersebut, saya akan menyarankan langsung mencoba dengan mencoba-kecuali untuk menghindari kondisi balapan:
try:
with open(path) as f:
f.read()
except OSError:
pass
akses
Tersedia untuk Unix dan Windows os.access, tetapi untuk menggunakan Anda harus melewati flag, dan itu tidak membedakan antara file dan direktori. Ini lebih digunakan untuk menguji apakah pengguna yang benar-benar memohon memiliki akses di lingkungan privilege yang tinggi:
import os
os.access(path, os.F_OK)
Itu juga menderita masalah kondisi ras yang sama seperti isfile. Dari dokumen :
Catatan: Menggunakan akses () untuk memeriksa apakah pengguna berwenang misalnya membuka file sebelum benar-benar melakukannya menggunakan open () menciptakan lubang keamanan, karena pengguna dapat mengeksploitasi interval waktu singkat antara memeriksa dan membuka file untuk memanipulasinya. Lebih disukai menggunakan teknik EAFP. Sebagai contoh:
if os.access("myfile", os.R_OK): with open("myfile") as fp: return fp.read() return "some default data"lebih baik ditulis sebagai:
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()
Hindari penggunaan os.access. Ini adalah fungsi tingkat rendah yang memiliki lebih banyak peluang untuk kesalahan pengguna daripada objek tingkat tinggi dan fungsi yang dibahas di atas.
Jawaban lain mengatakan ini tentang os.access:
Secara pribadi, saya lebih suka yang ini karena di bawah tenda, ia memanggil API asli (melalui "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c"), tetapi juga membuka gerbang untuk kemungkinan kesalahan pengguna, dan itu tidak sama Pythonic dengan varian lainnya. :
Jawaban ini mengatakan lebih memilih metode non-Pythonic, rawan kesalahan, tanpa pembenaran. Tampaknya mendorong pengguna untuk menggunakan API tingkat rendah tanpa memahaminya.
Ini juga menciptakan manajer konteks yang, dengan tanpa syarat kembali True, memungkinkan semua Pengecualian (termasuk KeyboardInterruptdan SystemExit!) Berlalu secara diam-diam, yang merupakan cara yang baik untuk menyembunyikan bug.
Ini tampaknya mendorong pengguna untuk mengadopsi praktik buruk.
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!"
Mengimpor osmemudahkan navigasi dan melakukan tindakan standar dengan sistem operasi Anda.
Untuk referensi juga lihat Cara memeriksa apakah file ada menggunakan Python?
Jika Anda membutuhkan operasi tingkat tinggi, gunakan shutil.
os.path.existsmengembalikan true untuk hal-hal yang bukan file, seperti direktori. Ini memberikan positif palsu. Lihat jawaban lain yang merekomendasikan os.path.isfile.
Menguji file dan folder dengan os.path.isfile(), os.path.isdir()danos.path.exists()
Dengan asumsi bahwa "jalur" adalah jalur yang valid, tabel ini menunjukkan apa yang dikembalikan oleh setiap fungsi untuk file dan folder:
Anda juga dapat menguji apakah file menggunakan jenis file tertentu os.path.splitext()untuk mendapatkan ekstensi (jika Anda belum mengetahuinya)
>>> 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
Di 2016 cara terbaik masih menggunakan os.path.isfile:
>>> os.path.isfile('/path/to/some/file.txt')
Atau dengan Python 3 Anda bisa menggunakan pathlib:
import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
...
pathlibadalah solusi OOP python untuk jalur. Anda dapat melakukan lebih banyak dengan itu. Jika Anda hanya perlu memeriksa keberadaan, keuntungannya tidak begitu besar.
Sepertinya tidak ada perbedaan fungsional yang bermakna antara coba / kecuali dan isfile(), jadi Anda harus menggunakan yang masuk akal.
Jika Anda ingin membaca file, jika ada, lakukan
try:
f = open(filepath)
except IOError:
print 'Oh dear.'
Tetapi jika Anda hanya ingin mengubah nama file jika ada, dan karena itu tidak perlu membukanya, lakukan
if os.path.isfile(filepath):
os.rename(filepath, filepath + '.old')
Jika Anda ingin menulis ke file, jika tidak ada, lakukan
# 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'
Jika Anda perlu mengunci file, itu masalah lain.
os.path.existsmengembalikan true untuk hal-hal yang bukan file, seperti direktori. Ini memberikan positif palsu. Lihat jawaban lain yang merekomendasikan os.path.isfile.
filepathdengan waktu yang tepat, dan BAM , Anda menimpa file target. Anda harus melakukannya open(filepath, 'wx')di try...exceptblok untuk menghindari masalah ini.
OSErrorjika filepath + '.old'sudah ada: "Pada Windows, jika dst sudah ada, OSError akan dimunculkan bahkan jika itu adalah file; mungkin tidak ada cara untuk mengimplementasikan penggantian nama atom ketika dst menamai file yang ada. "
os.replace portable melakukan penggantian diam dari file tujuan (identik dengan os.renameperilaku Linux) (hanya kesalahan jika nama tujuan ada dan merupakan direktori). Jadi Anda terjebak pada 2.x, tetapi pengguna Py3 telah memiliki opsi yang bagus selama beberapa tahun sekarang.
renamecontoh: Itu masih harus dilakukan dengan try/ except. os.rename(atau os.replacePython modern) adalah atom; membuatnya memeriksa lalu mengganti nama memperkenalkan perlombaan yang tidak perlu dan panggilan sistem tambahan. Lakukan sajatry: os.replace(filepath, filepath + '.old') except OSError: pass
Anda dapat mencoba ini (lebih aman):
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))
Ouput adalah:
([Errno 2] Tidak ada file atau direktori seperti itu: 'whatever.txt')
Kemudian, tergantung pada hasilnya, program Anda bisa tetap berjalan dari sana atau Anda dapat kode untuk menghentikannya jika Anda mau.
try
Meskipun saya selalu merekomendasikan penggunaan trydan exceptpernyataan, berikut adalah beberapa kemungkinan untuk Anda (favorit pribadi saya gunakan os.access):
Coba buka file:
Membuka file akan selalu memverifikasi keberadaan file. Anda dapat membuat fungsi seperti itu:
def File_Existence(filepath):
f = open(filepath)
return True
Jika itu False, itu akan menghentikan eksekusi dengan IOError atau OSError yang tidak ditangani di versi Python yang lebih baru. Untuk menangkap pengecualian, Anda harus menggunakan percobaan kecuali klausa. Tentu saja, Anda selalu dapat menggunakan trypernyataan exception` seperti itu (terima kasih kepada hsandt
karena membuat saya berpikir):
def File_Existence(filepath):
try:
f = open(filepath)
except IOError, OSError: # Note OSError is for later versions of Python
return False
return TrueGunakan os.path.exists(path):
Ini akan memeriksa keberadaan apa yang Anda tentukan. Namun, ia memeriksa file dan direktori jadi waspadalah tentang bagaimana Anda menggunakannya.
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")
FalseGunakan os.access(path, mode):
Ini akan memeriksa apakah Anda memiliki akses ke file. Itu akan memeriksa izin. Berdasarkan dokumentasi os.py, mengetik os.F_OK, itu akan memeriksa keberadaan jalan. Namun, menggunakan ini akan membuat lubang keamanan, karena seseorang dapat menyerang file Anda menggunakan waktu antara memeriksa izin dan membuka file. Anda sebaiknya langsung membuka file daripada memeriksa izinnya. ( EAFP vs LBYP ). Jika Anda tidak akan membuka file setelahnya, dan hanya memeriksa keberadaannya, maka Anda dapat menggunakan ini.
Bagaimanapun, ini:
>>> import os
>>> os.access("/is/a/file.txt", os.F_OK)
TrueSaya juga harus menyebutkan bahwa ada dua cara agar Anda tidak dapat memverifikasi keberadaan file. Entah masalahnya permission deniedatau no such file or directory. Jika Anda menangkap IOError, atur IOError as e(seperti opsi saya yang pertama), lalu ketik print(e.args)agar Anda dapat dengan mudah menentukan masalah Anda. Saya harap ini membantu! :)
Tanggal: 2017-12-04
Setiap solusi yang mungkin telah dicantumkan dalam jawaban lain.
Cara intuitif dan dapat diperdebatkan untuk memeriksa apakah ada file adalah sebagai berikut:
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')
Saya membuat cheatsheet lengkap untuk referensi Anda:
#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']}
Jika file ini untuk dibuka, Anda bisa menggunakan salah satu dari teknik berikut:
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!')
MEMPERBARUI
Hanya untuk menghindari kebingungan dan berdasarkan jawaban yang saya dapatkan, jawaban saat ini menemukan file atau direktori dengan nama yang diberikan.
os.path.existsmengembalikan true untuk hal-hal yang bukan file, seperti direktori. Ini memberikan positif palsu. Lihat jawaban lain yang merekomendasikan os.path.isfile.
if os.path.isfile(path_to_file):
try:
open(path_to_file)
pass
except IOError as e:
print "Unable to open file"
Memunculkan pengecualian dianggap sebagai pendekatan yang dapat diterima, dan Pythonic, untuk kontrol aliran dalam program Anda. Pertimbangkan untuk menangani file yang hilang dengan IOErrors. Dalam situasi ini, pengecualian IOError akan dimunculkan jika file ada tetapi pengguna tidak memiliki izin baca.
Anda dapat menulis saran Brian tanpa try:.
from contextlib import suppress
with suppress(IOError), open('filename'):
process()
suppressadalah bagian dari Python 3.4. Dalam rilis yang lebih lama Anda dapat dengan cepat menulis penekanan Anda sendiri:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
Saya penulis paket yang sudah ada sekitar 10 tahun, dan memiliki fungsi yang menjawab pertanyaan ini secara langsung. Pada dasarnya, jika Anda menggunakan sistem non-Windows, itu digunakan Popenuntuk mengakses find. Namun, jika Anda menggunakan Windows, ia bereplikasi finddengan walker sistem file yang efisien.
Kode itu sendiri tidak menggunakan tryblok ... kecuali dalam menentukan sistem operasi dan dengan demikian mengarahkan Anda ke gaya "Unix" findatau hand-buillt find. Tes waktu menunjukkan bahwa trylebih cepat dalam menentukan OS, jadi saya menggunakannya di sana (tapi tidak di tempat lain).
>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']
Dan dokter ...
>>> 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']
>>>
Implementasinya, jika Anda ingin melihatnya, ada di sini: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190
Anda dapat mengikuti tiga cara ini:
Catatan1:
os.path.isfileDigunakan hanya untuk file
import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists
Note2:
os.path.existsDigunakan untuk file dan direktori
import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists
The
pathlib.PathMetode (termasuk dalam Python 3 +, diinstal dengan pip untuk Python 2)
from pathlib import Path
Path(filename).exists()
Menambahkan satu variasi kecil lagi yang tidak persis tercermin dalam jawaban lainnya.
Ini akan menangani case dari string file_pathsedang Noneatau kosong.
def file_exists(file_path):
if not file_path:
return False
elif not os.path.isfile(file_path):
return False
else:
return True
Menambahkan varian berdasarkan saran dari Shahbaz
def file_exists(file_path):
if not file_path:
return False
else:
return os.path.isfile(file_path)
Menambahkan varian berdasarkan saran dari Peter Wood
def file_exists(file_path):
return file_path and os.path.isfile(file_path):
if (x) return true; else return false;benar-benar adil return x. Empat baris terakhir Anda bisa menjadi return os.path.isfile(file_path). Sementara kita melakukannya, seluruh fungsi dapat disederhanakan return file_path and os.path.isfile(file_path).
return xdalam hal if (x). Python akan menganggap string kosong False dalam hal ini kita akan mengembalikan string kosong daripada bool. Tujuan dari fungsi ini adalah untuk selalu mengembalikan bool.
xsudah os.path.isfile(..)jadi bool.
os.path.isfile(None)memunculkan pengecualian yang mengapa saya menambahkan cek jika. Saya mungkin hanya bisa membungkusnya dengan coba / kecuali tetapi saya merasa itu lebih eksplisit seperti ini.
return file_path and os.path.isfile(file_path)
Berikut adalah perintah Python 1 baris untuk lingkungan baris perintah Linux. Saya menemukan ini SANGAT HANDY karena saya bukan orang Bash panas.
python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"
Saya harap ini bermanfaat.
[ -f "${file}" ] && echo "file found" || echo "file not found"(yang sama dengan if [ ... ]; then ...; else ...; fi).
Anda dapat menggunakan pustaka "OS" dari Python:
>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt")
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False
os.path.existsmengembalikan true untuk hal-hal yang bukan file, seperti direktori. Ini memberikan positif palsu. Lihat jawaban lain yang merekomendasikan os.path.isfile.
existssaja. Jika tujuannya adalah untuk menentukan apakah aman untuk membuka file yang mungkin ada, maka kritik tersebut dapat dibenarkan dan ada tidak cukup tepat. Sayangnya, OP tidak menentukan tujuan mana yang diinginkan (dan mungkin tidak akan melakukannya lagi).
Bagaimana cara memeriksa apakah ada file, tanpa menggunakan pernyataan coba?
Pada 2016, ini masih bisa dibilang cara termudah untuk memeriksa apakah kedua file itu ada dan apakah itu file:
import os
os.path.isfile('./file.txt') # Returns True if exists, else False
isfilesebenarnya hanya metode pembantu yang secara internal menggunakan os.statdan di stat.S_ISREG(mode)bawahnya. Ini os.statadalah metode tingkat rendah yang akan memberi Anda informasi terperinci tentang file, direktori, soket, buffer, dan banyak lagi. Lebih lanjut tentang os.stat di sini
Catatan: Namun, pendekatan ini tidak akan mengunci file dengan cara apa pun dan karena itu kode Anda dapat menjadi rentan terhadap bug " waktu pemeriksaan ke waktu penggunaan " ( TOCTTOU ).
Jadi, meningkatkan pengecualian dianggap sebagai pendekatan aliran kontrol yang dapat diterima, dan Pythonic, dalam program Anda. Dan orang harus mempertimbangkan menangani file yang hilang dengan IOErrors, bukan ifpernyataan ( hanya saran ).
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)
isReadableFile(path,fileName)akan kembali Truejika file dapat dijangkau dan dibaca oleh proses \ program \ utas