Jawaban:
Jika alasan Anda mengecek adalah agar Anda dapat melakukan sesuatu seperti if file_exists: open_it()
, lebih aman menggunakan upaya try
sekitar 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
True
jika 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, pathlib
modul ini menawarkan pendekatan berorientasi objek (backported ke pathlib2
dalam 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 Path
objek 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 try
blok:
try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
FileNotFoundError
diperkenalkan di Python 3. Jika Anda juga perlu mendukung Python 2.7 dan juga Python 3, Anda dapat menggunakan IOError
sebagai gantinya ( FileNotFoundError
subkelas mana ) stackoverflow.com/a/21368457/1960959
open('file', 'r+')
) dan kemudian mencari sampai akhir.
Anda memiliki os.path.exists
fungsi:
import os.path
os.path.exists(file_path)
Ini mengembalikan True
file 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 True
untuk 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.path
lagi karena sudah menjadi bagian dari os
. Anda hanya perlu mengimpor os.path
jika Anda hanya akan menggunakan fungsi dari os.path
dan bukan dari os
itu sendiri, untuk mengimpor hal yang lebih kecil, tetapi saat Anda menggunakan os.access
dan 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.lexists
untuk perilaku yang sedikit berbeda)
os.path.exists(path)
Kembali
True
jika jalur merujuk ke jalur yang ada atau deskriptor file terbuka. PengembalianFalse
untuk tautan simbolis yang rusak. Pada beberapa platform, fungsi ini dapat kembaliFalse
jika 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 True
itu 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.isfile
perilaku (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 result
Gunakan [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.scandir
bila 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_OK
panggilan, 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.glob
juga) 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 glob
metode tanpa o wildcard, fungsinya cerdas: Ia tahu Anda hanya dapat memiliki satu hit, sehingga menyederhanakan globbing menjadi adil os.path.isdir
atauos.path.lexists
(tergantung pada apakah path berakhir /
).
os.path.isdir
atau os.path.lexist
karena 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/except
blok 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...except
tidak 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 Path
objek dengan nama file, dan periksa is_file
metode (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 isfile
dari os.path
modul:
>>> 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 try
di mana-mana dalam implementasinya.
Karena Python menggunakan di try
mana-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 Path
objek baru di pathlib
. Catatan yang .exists
tidak 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, NamedTemporaryFile
menghapus 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_file
menggunakan 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 try
karena 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 try
pernyataan dengan menggunakan suppress
manajer konteks.
suppress
Python 3.4 memberi kita suppress
manajer konteks (sebelumnya ignore
manajer konteks), yang melakukan hal yang sama persis secara semantik dalam lebih sedikit baris, sementara juga (setidaknya secara dangkal) memenuhi yang asli meminta untuk menghindari try
pernyataan:
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 try
wasiat akan lebih bertele-tele daripada dengan. Saya percaya ini sebenarnya adalah satu-satunya jawaban yang tidak digunakan try
pada 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 OSError
dan 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 KeyboardInterrupt
dan 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 os
memudahkan 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.exists
mengembalikan 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():
...
pathlib
adalah 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.exists
mengembalikan true untuk hal-hal yang bukan file, seperti direktori. Ini memberikan positif palsu. Lihat jawaban lain yang merekomendasikan os.path.isfile
.
filepath
dengan waktu yang tepat, dan BAM , Anda menimpa file target. Anda harus melakukannya open(filepath, 'wx')
di try...except
blok untuk menghindari masalah ini.
OSError
jika 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.rename
perilaku 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.
rename
contoh: Itu masih harus dilakukan dengan try
/ except
. os.rename
(atau os.replace
Python 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 try
dan except
pernyataan, 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 try
pernyataan 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 True
Gunakan 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")
False
Gunakan 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)
True
Saya juga harus menyebutkan bahwa ada dua cara agar Anda tidak dapat memverifikasi keberadaan file. Entah masalahnya permission denied
atau 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.exists
mengembalikan 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()
suppress
adalah 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 Popen
untuk mengakses find
. Namun, jika Anda menggunakan Windows, ia bereplikasi find
dengan walker sistem file yang efisien.
Kode itu sendiri tidak menggunakan try
blok ... kecuali dalam menentukan sistem operasi dan dengan demikian mengarahkan Anda ke gaya "Unix" find
atau hand-buillt find
. Tes waktu menunjukkan bahwa try
lebih 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.isfile
Digunakan 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.exists
Digunakan 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.Path
Metode (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_path
sedang None
atau 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 x
dalam 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.
x
sudah 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.exists
mengembalikan true untuk hal-hal yang bukan file, seperti direktori. Ini memberikan positif palsu. Lihat jawaban lain yang merekomendasikan os.path.isfile
.
exists
saja. 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
isfile
sebenarnya hanya metode pembantu yang secara internal menggunakan os.stat
dan di stat.S_ISREG(mode)
bawahnya. Ini os.stat
adalah 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 if
pernyataan ( 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 True
jika file dapat dijangkau dan dibaca oleh proses \ program \ utas