İfadeyi kullanmadan bir dosyanın var olup olmadığını nasıl kontrol ederim try
?
İfadeyi kullanmadan bir dosyanın var olup olmadığını nasıl kontrol ederim try
?
Yanıtlar:
Eğer kontrol etmenizin nedeni böyle bir şey yapabilmenizse if file_exists: open_it()
, onu try
açma girişiminde kullanmak daha güvenlidir . Kontrol etme ve ardından açma, silindiğiniz veya taşındığınız dosya veya kontrol ettiğiniz zaman ile açmaya çalıştığınız zaman arasında bir risk oluşturur.
Dosyayı hemen açmayı planlamıyorsanız, şunu kullanabilirsiniz: os.path.isfile
İade
True
yolu varolan normal dosya ise. Her iki yüzden bu sembolik bağlantıları izler islink () ve isfile () aynı yolu için doğru olabilir.
import os.path
os.path.isfile(fname)
bunun bir dosya olduğundan emin olmanız gerekiyorsa.
Python 3.4'ten başlayarak, pathlib
modül nesne yönelimli bir yaklaşım sunar ( pathlib2
Python 2.7'de desteklenmektedir):
from pathlib import Path
my_file = Path("/path/to/file")
if my_file.is_file():
# file exists
Bir dizini kontrol etmek için şunları yapın:
if my_file.is_dir():
# directory exists
Bir Path
nesnenin dosya veya dizin olup olmadığından bağımsız olarak var olup olmadığını kontrol etmek için şunu kullanın exists()
:
if my_file.exists():
# path exists
resolve(strict=True)
Bir try
blokta da kullanabilirsiniz :
try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
open('file', 'r+')
) için açıp sonuna kadar arayabilirsiniz.
Sen var os.path.exists
fonksiyonu:
import os.path
os.path.exists(file_path)
Bu True
hem dosyalar hem de dizinler için geri döner ancak bunun yerine
os.path.isfile(file_path)
özel olarak bir dosya olup olmadığını test etmek için. Simgelerini takip eder.
Bunun aksine isfile()
, dizinler için exists()
dönecektir True
. Yalnızca düz dosya veya ayrıca dizinleri istiyorsanız bağlı Yani, kullanacağız isfile()
ya exists()
. İşte bazı basit REPL çıktısı:
>>> 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
Kullanım os.path.isfile()
ile 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()
false değerini döndürür.
import os
için import os.path
tekrar yapmanız gerekmiyor os
. Daha küçük bir şey içe aktarmak için yalnızca kendisinden değil os.path
, yalnızca işlevler kullanacaksanız içe aktarmanız gerekir , ancak kullandıkça ve ikinci içe aktarmaya gerek yoktur. os.path
os
os.access
os.R_OK
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
Her ne kadar mümkün olan her yol mevcut cevaplarda (en az bir tanesi) listelenmiş olsa da (örneğin Python 3.4'e özgü şeyler eklendi), her şeyi birlikte gruplandırmaya çalışacağım.
Not : Göndereceğim her Python standart kütüphane kodunun parçası 3.5.3 sürümüne aittir .
Sorun bildirimi :
Olası çözümler :
[Python 3]: o. Yol. Varlığından ( yol ) (ayrıca gibi diğer fonksiyon aile üyelerini kontrol os.path.isfile
, os.path.isdir
, os.path.lexists
biraz farklı davranışlar için)
os.path.exists(path)
Dönüş
True
ise yol , varolan bir yola veya açık dosya tanımlayıcı karşılık gelir.False
Bozuk sembolik bağlantıları döndürür . Bazı platformlarda, yol fiziksel olarak var olsa bile, istenen dosyada os.stat ()False
yürütülmesine izin verilmezse bu işlev dönebilir .
Hepsi iyi, ancak ithalat ağacını takip ediyorsanız:
os.path
- posixpath.py ( ntpath.py )
genericpath.py , satır ~ # 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
[Python 3]: os etrafında sadece bir deneme / blok hariç . stat ( yol, *, dir_fd = Yok, follow_symlinks = Doğru ) . Yani, .kodunuz deneyin / hariç ücretsiz, ancak framestack içinde düşürmek var (en azından) bir tür bloğu. Bu, diğer işlevler için de geçerlidir ( dahil os.path.isfile
).
1.1. [Python 3]: Yol. is_file ()
Kaputun altında, tam olarak aynı şeyi yapar ( 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]: Deyim Bağlam Yöneticileri ile . Ya:
Bir tane yarat:
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 ...)
Ve onun kullanımı - Ben çoğaltmak edeceğiz os.path.isfile
(bu sadece amaçları göstermek için, do olduğuna dikkat davranışı değil böyle kod yazmak girişiminde üretim ):
import os
import stat
def isfile_seaman(path): # Dummy func
result = False
with Swallow():
result = stat.S_ISREG(os.stat(path).st_mode)
return result
[Python 3]: contextlib kullanın . supress ( * istisnalar ) - istisnaları seçici olarak bastırmak için özel olarak tasarlanmıştır
Ama onlar üzerinde sarmalayıcıları gibi görünüyor denemede / hariç / else / nihayet blokları gibi [Python 3]: ile deyim devletler:
Bu, ortak denemeye izin verir ... hariç ... son olarak, uygun yeniden kullanım için kullanım kalıplarının kapsüllenmesini sağlar.
Dosya sistemi geçiş işlevleri (ve eşleşen öğeler için sonuçları arayın)
[Python 3]: os. Python v 3.5 + üzerinde listdir ( path = '.' ) (veya [Python 3]: os. scandir ( path = '.' ) , backport: [PyPI]: scandir )
Kaputun altında her ikisi de şunları kullanır:
[GitHub] aracılığıyla : python / cpython - (ana) cpython / Modüller / posixmodule.c
Kullanılması scandir () yerine listdir () çünkü önemli ölçüde ayrıca dosya türü veya dosya özniteliği bilgiye ihtiyacı kod performansını artırabilir os.DirEntry bir dizin tararken işletim sistemi bunu sağlıyorsa bu bilgileri açığa nesneleri. Tüm os.DirEntry yöntemleri bir sistem çağrısı gerçekleştirebilir, ancak is_dir () ve is_file () genellikle sembolik bağlantılar için yalnızca bir sistem çağrısı gerektirir; os.DirEntry.stat () her zaman Unix üzerinde bir sistem çağrısı gerektirir, ancak Windows'daki sembolik bağlantılar için yalnızca bir tane gerektirir.
os.listdir
( os.scandir
varsa)glob.glob
)
os.listdir
Bu klasörler üzerinde yinelendiğinden, (çoğu durumda) sorunumuz için verimsizdirler (joker karakterli olmayan glob bing gibi istisnalar vardır - @ShadowRanger'ın işaret ettiği gibi), bu yüzden ısrar etmeyeceğim. Bazı durumlarda dosya adı işlemenin gerekli olabileceğinden bahsetmiyorum bile.
[Python 3]: os. davranışı yakın olan erişim ( yol, mod, *, dir_fd = Yok, efektif_ids = Yanlış, follow_symlinks = Doğru )os.path.exists
(aslında 2. argüman nedeniyle daha geniştir )
... çağıran kullanıcının yola belirtilen erişime sahip olup olmadığını test edin . yolun varlığını test etmek için mod F_OK olmalıdır ...
os.access("/tmp", os.F_OK)
Ben de işin bu yana C , kaputun altında, bu aramaları çünkü hem bu yöntemi kullanmak yerli API ler (via yine "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c" ), ama aynı zamanda mümkün için bir kapı açar kullanıcıya hataları ve diğer varyantlar gibi Python ic değil . Yani, @AaronHall'ın haklı olarak işaret ettiği gibi, ne yaptığınızı bilmiyorsanız kullanmayın:
Not : Yerel API'leri çağırmak [Python 3] aracılığıyla da mümkündür : ctypes - Python için yabancı bir işlev kütüphanesi , ancak çoğu durumda daha karmaşıktır.
( Win özel): yana vcruntime * ( msvcr * ) .dll ihracatı bir [MS.Docs]: _access, _waccess yanı fonksiyon ailesi, burada bir örnek:
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
Notlar :
os.F_OK
, çağrıda kullanıyorum , ama bu sadece netlik için (değeri 0 )
LNX ( Ubtu (16 x 64) sıra) muadili:
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
Notlar :
Bunun yerine , sistemler arasında değişiklik gösterebilen (ve büyük olasılıkla) hardcoding libc'nin yolu ( "/lib/x86_64-linux-gnu/libc.so.6" ), Hiçbiri (veya boş dize) CDLL yapıcısına aktarılabilir ( ctypes.CDLL(None).access(b"/tmp", os.F_OK)
). Göre [man7]: Dlopen (3) :
Eğer dosya adı NULL, sonra döndü sap ana programa içindir. Dlsym () öğesine verildiğinde , bu tanıtıcı ana programda bir sembol aramasına, ardından program başlangıcında yüklenen tüm paylaşılan nesnelere ve sonra da dlopen () tarafından RTLD_GLOBAL bayrağıyla yüklenen tüm paylaşılan nesnelere neden olur .
__declspec(dllexport)
Dosya sistemi özelliklerine sahip üçüncü taraf bir modül yükleyin
Büyük olasılıkla, yukarıdaki yollardan birine dayanacaktır (belki küçük özelleştirmelerle).
Bir örnek olarak, (yine Win spesifik) [GitHub]: mhammond / pywin32 - Python Pencereler (pywin32) Uzantıları için bir olduğunu, Python üzerinde sarıcı WINAPI s.
Ancak, bu daha çok bir geçici çözüm gibi olduğundan, burada duruyorum.
Başka bir (topal) geçici çözüm ( gainarie ) (ben demek istediğim gibi) sysadmin yaklaşım: kabuk komutlarını yürütmek için bir sarıcı olarak Python kullanın
Kazan :
(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
Sonuç :
Son not (lar) :
glob.iglob
(ve glob.glob
de) dayanıyoros.scandir
, bu yüzden şimdi tembel; 10M dosyalarından oluşan bir dizindeki ilk isabeti almak için, yalnızca ilk isabete ulaşıncaya kadar tarama yaparsınız. Ve 3.6 öncesi bile, glob
herhangi bir joker karakter olmadan yöntem kullanırsanız , işlev akıllıdır: Sadece bir vuruş yapabileceğinizi bilir, bu nedenle globbing'i sadece os.path.isdir
ya daos.path.lexists
(yolun bitip bitmediğine bağlı olarak) basitleştirir/
.
os.path.isdir
veya os.path.lexist
Python düzeyinde işlev çağrıları ve dize etkin yolun geçerli olduğuna karar vermeden önce işlemler, ancak daha yavaş siparişleri olan ek bir sistem çağrısı veya G / Ç çalışması yoktur).
Bir dosyanın var olup olmadığını kontrol etmenin en basit yolu budur. Sadece çünkü sen gelmez işaretlendiğinde dosya var garanti Açmak için gereken zaman olacağı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")
Python 3.4+ , nesneye yönelik bir yol modülüne sahiptir: pathlib . Bu yeni modülü kullanarak, aşağıdaki gibi bir dosyanın var olup olmadığını kontrol edebilirsiniz:
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
try/except
Dosyaları açarken yine de bir blok kullanabilirsiniz (ve genellikle kullanmalısınız) :
try:
with p.open() as f:
# do awesome stuff
except OSError:
print('Well darn.')
Pathlib modülünün içinde çok güzel şeyler var: uygun globbing, dosyanın sahibini kontrol etme, daha kolay yol birleştirme, vb. Daha eski bir Python kullanıyorsanız (sürüm 2.6 veya üstü), yine de pathlib'i pip ile kurabilirsiniz:
# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2
Ardından aşağıdaki gibi içe aktarın:
# Older Python versions
import pathlib2 as pathlib
Try ifadesini tercih edin. Daha iyi bir stil olarak kabul edilir ve yarış koşullarından kaçınır.
Benim sözüme güvenme. Bu teori için bolca destek var. İşte bir çift:
try...except
çözülmesine yardımcı olmaz.
except:
yan tümcesine koymak , kodunuzun bu bölümünde ortaya çıkan bir istisnanın kafa karıştırıcı bir mesaj oluşturacağını ( ilkinin işlenmesi.)
Try deyimi kullanmadan Python kullanarak bir dosyanın var olup olmadığını nasıl kontrol edebilirim?
Şimdi Python 3.4'ten bu yana kullanılabilir Path
, dosya adına sahip bir nesneyi içe aktarın ve somutlaştırın ve is_file
yöntemi kontrol edin (bunun normal dosyalara işaret eden semboller için de True döndürdüğünü unutmayın):
>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False
Eğer Python 2 işlem yapıyorsanız, sen pypi gelen pathlib modülünü backport edebilir pathlib2
veya başka kontrol isfile
gelen os.path
modül:
>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False
Şimdi yukarıdaki muhtemelen en iyi pragmatik doğrudan cevaptır, ancak bir yarış koşulu olasılığı (ne yapmaya çalıştığınıza bağlı olarak) ve temeldeki uygulamanın bir kullandığı gerçeği vardır try
, ancak Python try
uygulamasında her yerde kullanır .
Python try
her yerde kullandığı için, onu kullanan bir uygulamadan kaçınmak için gerçekten hiçbir neden yoktur.
Ancak bu cevabın geri kalanı bu uyarıları dikkate almaya çalışır.
Python 3.4'ten beri kullanılabilir, içindeki yeni Path
nesneyi kullanın pathlib
. Bunun .exists
doğru olmadığını unutmayın , çünkü dizinler dosya değildir ( her şeyin bir dosya olduğu unix anlamı hariç ).
>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True
Bu yüzden şunu kullanmalıyız is_file
:
>>> root.is_file()
False
İşte yardım is_file
:
is_file(self)
Whether this path is a regular file (also True for symlinks pointing
to regular files).
Öyleyse bir dosya olduğunu bildiğimiz bir dosya alalım:
>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True
Varsayılan olarak, NamedTemporaryFile
kapatıldığında dosyayı siler (ve daha fazla referans yoksa otomatik olarak kapanır).
>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False
Eğer içine kazmak ise uygulanması olsa da, bunu göreceksiniz is_file
kullanımları 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
Biz mi try
o yarış koşulları önler çünkü. İle try
, dosyanızı orada okumayı bekledikten sonra okumaya çalışırsınız ve yoksa, istisnayı yakalar ve geri dönüş davranışının anlamlı olduğu her şeyi gerçekleştirirsiniz.
Bir dosyayı okumaya çalışmadan önce var olup olmadığını kontrol etmek istiyorsanız ve dosyayı siliyor olabilirsiniz ve birden fazla iş parçacığı veya işlem kullanıyor olabilirsiniz veya başka bir program bu dosyayı bilir ve silebilir - silme şansınız vardır Eğer varlığını kontrol ederseniz bir yarış koşulu var, çünkü daha sonra durumu (varlığı) değişmeden açmak için yarışıyorsunuz .
Yarış koşullarının hatalarını ayıklamak çok zordur çünkü programınızın başarısız olmasına neden olabilecekleri çok küçük bir pencere vardır.
Ancak bu sizin motivasyonunuzsa, bağlam yöneticisini kullanarak bir ifadenin değerini elde edebilirsiniz .try
suppress
suppress
Python 3.4 bize suppress
daha ignore
az satırda semantik olarak tam olarak aynı şeyi yapan bağlam yöneticisini (daha önce bağlam yöneticisi) verirken, aynı zamanda (en azından yüzeysel olarak) orijinal try
ifadeyi bir ifadeden kaçınmak için karşılar :
from contextlib import suppress
from pathlib import Path
Kullanımı:
>>> with suppress(OSError), Path('doesnotexist').open() as f:
... for line in f:
... print(line)
...
>>>
>>> with suppress(OSError):
... Path('doesnotexist').unlink()
...
>>>
Daha önceki Python'lar için, kendinizinkini yuvarlayabilirsiniz suppress
, ancak bir try
istek olmadan daha ayrıntılı olacaktır. Bunun aslındatry
Python 3.4'ten önce uygulanabilen Python'da herhangi bir düzeyde kullanmayan tek cevap olduğuna inanıyorum çünkü bunun yerine bir bağlam yöneticisi kullanıyor:
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)
Belki bir denemeyle daha kolay:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
isfile
import os
os.path.isfile(path)
dan docs :
os.path.isfile(path)
Yol varolan normal bir dosyaysa True döndür. Bu sembolik bağlantıları izler, böylece hem
islink()
veisfile()
aynı yolu için doğru olabilir.
Ancak bu işlevin kaynağını incelerseniz, aslında bir try ifadesi kullandığını görürsünüz:
# 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
Yaptığı tek şey, ilgili istatistikleri alıp alamayacağını görmek için verilen yolu kullanmak, yakalamak OSError
ve istisnayı yükseltmediyse bir dosya olup olmadığını kontrol etmektir.
Dosyayla bir şey yapmak istiyorsanız, bir yarış durumundan kaçınmak için doğrudan bir deneme-denemeyle denemenizi öneririz:
try:
with open(path) as f:
f.read()
except OSError:
pass
os.access
Unix ve Windows os.access
için kullanılabilir, ancak kullanmak için bayraklar geçirmeniz gerekir ve dosyalar ve dizinler arasında ayrım yapmaz. Bu, gerçek davet eden kullanıcının yükseltilmiş bir ayrıcalık ortamında erişiminin olup olmadığını test etmek için daha çok kullanılır:
import os
os.access(path, os.F_OK)
Aynı ırk koşulu problemlerinden de muzdariptir isfile
. Gönderen docs :
Not: Bir kullanıcının gerçekten dosyayı açmadan önce örneğin bir dosyayı açma yetkisine sahip olup olmadığını kontrol etmek için access () kullanılması, open () kullanarak bir güvenlik deliği oluşturur, çünkü kullanıcı dosyayı denetlemek ve açmak için dosyayı açma arasındaki kısa zaman aralığından yararlanabilir. EAFP tekniklerinin kullanılması tercih edilir. Örneğin:
if os.access("myfile", os.R_OK): with open("myfile") as fp: return fp.read() return "some default data"
daha iyi şöyle yazılır:
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()
Kullanmaktan kaçının os.access
. Yukarıda tartışılan üst düzey nesnelerden ve işlevlerden daha fazla kullanıcı hatası için fırsatlara sahip düşük düzeyli bir işlevdir.
Başka bir cevap şöyle diyor os.access
:
Şahsen ben bunu tercih ediyorum çünkü kaputun altında, yerel API'leri çağırıyor ("$ {PYTHON_SRC_DIR} /Modules/posixmodule.c" aracılığıyla), ancak aynı zamanda olası kullanıcı hataları için bir kapı açıyor ve diğer varyantlar gibi Pythonic değil :
Bu cevap, Pythonic olmayan, hataya açık bir yöntemi tercih ettiğini ve gerekçesiz olduğunu söylüyor. Kullanıcıları anlamadan düşük düzeyli API'leri kullanmaya teşvik ediyor gibi görünüyor.
Ayrıca, koşulsuz olarak geri dönerek True
, tüm İstisnaların ( KeyboardInterrupt
ve SystemExit
!) Sessizce geçmesine izin veren, hataları gizlemenin iyi bir yolu olan bir bağlam yöneticisi oluşturur .
Bu, kullanıcıları kötü uygulamaları benimsemeye teşvik ediyor gibi görünüyor.
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!"
İçe aktarma os
, işletim sisteminizde standart işlemlerde gezinmeyi ve gerçekleştirmeyi kolaylaştırır.
Referans için ayrıca bkz. Python kullanarak bir dosyanın var olup olmadığı nasıl kontrol edilir?
Üst düzey işlemlere ihtiyacınız varsa kullanın shutil
.
os.path.exists
dizinler gibi dosya olmayan şeyler için true değerini döndürür. Bu yanlış pozitifler verir. Önerilen diğer yanıtlara bakın os.path.isfile
.
Dosya ve klasörleri test etme os.path.isfile()
, os.path.isdir()
veos.path.exists()
"Yol" un geçerli bir yol olduğunu varsayarsak, bu tablo, dosyalar ve klasörler için her işlev tarafından döndürülenleri gösterir:
Ayrıca, bir dosyayı os.path.splitext()
uzantıyı almak için kullanarak belirli bir dosya türü olup olmadığını da test edebilirsiniz (henüz bilmiyorsanız)
>>> 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
2016'da en iyi yol hala kullanıyor os.path.isfile
:
>>> os.path.isfile('/path/to/some/file.txt')
Veya Python 3'te şunları kullanabilirsiniz pathlib
:
import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
...
pathlib
python'un yollar için OOP çözümüdür. Bununla daha fazlasını yapabilirsiniz. Sadece varlığı kontrol etmeniz gerekiyorsa, avantaj o kadar büyük değildir.
Deneme / hariç arasında anlamlı bir işlevsel fark var gibi görünmüyor isfile()
bu yüzden hangisinin mantıklı olduğunu kullanmalısınız.
Bir dosyayı okumak istiyorsanız, varsa
try:
f = open(filepath)
except IOError:
print 'Oh dear.'
Ancak bir dosyayı varsa yeniden adlandırmak istiyorsanız ve bu nedenle açmanız gerekmiyorsa,
if os.path.isfile(filepath):
os.rename(filepath, filepath + '.old')
Bir dosyaya yazmak istiyorsanız, yoksa
# 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'
Dosya kilitleme gerekiyorsa, bu farklı bir konudur.
os.path.exists
dizinler gibi dosya olmayan şeyler için true değerini döndürür. Bu yanlış pozitifler verir. Önerilen diğer yanıtlara bakın os.path.isfile
.
filepath
doğru zamanlama ile adlandırılmış bir bağlantı oluşturuyorum ve BAM , hedef dosyanın üzerine yazıyorsunuz. Sorunu önlemek için open(filepath, 'wx')
bir try...except
blokta yapmanız gerekir .
OSError
eğer filepath + '.old'
"dst zaten varsa Windows'ta, OSError bir dosya olsa bile yükseltilecek; zaman dst bir atomik yeniden adlandırma uygulamak için bir yol olabilir: zaten var mevcut bir dosyayı adlandırır. "
os.replace
itibaren, hedef dosyanın sessiz bir şekilde değiştirilmesini sağlar ( os.rename
Linux'un davranışı ile aynıdır ) (yalnızca hedef adı varsa ve bir dizinse hata verir). Yani 2.x'e bağlı kaldınız, ancak Py3 kullanıcıları birkaç yıldır iyi bir seçeneğe sahipler.
rename
Örneğin: Hala ile yapılmalıdır try
/ ' except
. os.rename
(veya os.replace
modern Python'da) atomiktir; kontrol etmenin ardından yeniden adlandırın, gereksiz bir yarış ve ek sistem çağrıları sunar. Just dotry: os.replace(filepath, filepath + '.old') except OSError: pass
Bunu deneyebilirsiniz (daha güvenli):
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))
Çıkış şu şekilde olur:
([Errno 2] Böyle bir dosya veya dizin yok: 'whatever.txt')
Daha sonra, sonuca bağlı olarak, programınız oradan çalışmaya devam edebilir veya isterseniz durdurmak için kodlayabilirsiniz.
try
Her zaman try
ve except
ifadeleri kullanmanızı öneririm , işte size birkaç olasılık (kişisel favorim kullanıyor os.access
):
Dosyayı açmayı deneyin:
Dosyanın açılması her zaman dosyanın varlığını doğrular. Bunun gibi bir işlev yapabilirsiniz:
def File_Existence(filepath):
f = open(filepath)
return True
Yanlışsa, Python'un sonraki sürümlerinde işlenmemiş bir IOError veya OSError ile yürütmeyi durduracaktır. İstisnayı yakalamak için, fıkra dışında bir deneme kullanmanız gerekir. Tabii ki, her zaman try
böyle bir `` deyimi '' kullanabilirsiniz (
beni düşündüren hsandt sayesinde ):
def File_Existence(filepath):
try:
f = open(filepath)
except IOError, OSError: # Note OSError is for later versions of Python
return False
return True
Kullanım os.path.exists(path)
:
Bu, belirttiğiniz şeyin varlığını kontrol edecektir. Ancak, dosya ve dizinleri kontrol eder, bu yüzden nasıl kullandığınız konusunda dikkatli olun.
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
Kullanım os.access(path, mode)
:
Bu, dosyaya erişiminizin olup olmadığını kontrol eder. İzinleri kontrol eder. Osppy belgelerine dayanarak, yazarak os.F_OK
yolun varlığını kontrol eder. Ancak, bir kullanıcı izinleri denetleme ve dosyayı açma arasındaki süreyi kullanarak dosyaya saldırabileceğinden, bunu kullanmak bir güvenlik açığı oluşturur. Bunun yerine, izinlerini denetlemek yerine doğrudan dosyayı açmaya gitmelisiniz. ( EAFP vs LBYP ). Daha sonra dosyayı açmayacak ve sadece varlığını kontrol edecekseniz, bunu kullanabilirsiniz.
Her neyse, burada:
>>> import os
>>> os.access("/is/a/file.txt", os.F_OK)
True
Ayrıca, bir dosyanın varlığını doğrulayamayacağınız iki yol olduğunu da belirtmeliyim. Ya sorun permission denied
ya olacak no such file or directory
. Bir yakalarsanız IOError
, IOError as e
(ilk seçeneğim gibi) ayarlayın ve print(e.args)
sorununuzu umarım belirleyebilmeniz için yazın. Umut ediyorum bu yardım eder! :)
Tarih: 2017/12/04
Olası her çözüm diğer cevaplarda listelenmiştir.
Bir dosyanın var olup olmadığını kontrol etmenin sezgisel ve tartışmalı bir yolu şudur:
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')
Referans için kapsamlı bir hile sayfası yaptım:
#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']}
Dosya açmak içinse, aşağıdaki tekniklerden birini kullanabilirsiniz:
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!')
GÜNCELLEME
Sadece karışıklıktan kaçınmak ve aldığım cevaplara dayanarak, mevcut cevap verilen dosyaya sahip bir dosya veya dizin bulur .
os.path.exists
dizinler gibi dosya olmayan şeyler için true değerini döndürür. Bu yanlış pozitifler verir. Önerilen diğer yanıtlara bakın 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"
İstisnaları yükseltmek, programınızdaki akış kontrolü için kabul edilebilir ve Pythonic bir yaklaşım olarak kabul edilir. IOErrors ile eksik dosyaları ele almayı düşünün. Bu durumda, dosya varsa ancak kullanıcının okuma izinleri yoksa bir IOError istisnası yükseltilir.
Brian'ın önerisini olmadan yazabilirsiniz try:
.
from contextlib import suppress
with suppress(IOError), open('filename'):
process()
suppress
Python 3.4'ün bir parçasıdır. Eski sürümlerde hızlı bir şekilde kendi bastırmanızı yazabilirsiniz:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
Yaklaşık 10 yıldır var olan bir paketin yazarıyım ve bu soruyu doğrudan ele alan bir işlevi var. Temel olarak, Windows olmayan bir sistemdeyseniz Popen
erişmek için kullanır find
. Ancak, Windows kullanıyorsanız, find
verimli bir dosya sistemi yürütücüsüyle çoğalır .
Kodun kendisi bir try
blok kullanmaz … işletim sistemini belirlemek ve böylece sizi "Unix" find
tarzına veya el-buillt'e yönlendirmek dışında find
. Zamanlama testleri try
, işletim sisteminin belirlenmesinde daha hızlı olduğunu gösterdi , bu yüzden orada bir tane kullandım (ancak başka hiçbir yerde).
>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']
Ve doktor…
>>> 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']
>>>
Bakmak istediğiniz uygulama burada: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190
Bu üç yolu takip edebilirsiniz:
Not1:
os.path.isfile
Yalnızca dosyalar için kullanılır
import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists
Not2:
os.path.exists
Hem dosyalar hem de dizinler için kullanılır
import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists
pathlib.Path
Yöntemi (Python dahil 3+, Python 2 pip ile kurulabilir)
from pathlib import Path
Path(filename).exists()
Diğer cevaplara tam olarak yansıtılmayan bir küçük değişiklik daha eklemek.
Bu, file_path
varlık None
veya boş dizenin durumunu ele alır .
def file_exists(file_path):
if not file_path:
return False
elif not os.path.isfile(file_path):
return False
else:
return True
Shahbaz'ın önerisine dayanan bir varyant ekleme
def file_exists(file_path):
if not file_path:
return False
else:
return os.path.isfile(file_path)
Peter Wood'un önerisine dayanan bir varyant ekleme
def file_exists(file_path):
return file_path and os.path.isfile(file_path):
if (x) return true; else return false;
gerçekten sadece return x
. Son dört çizginiz olabilir return os.path.isfile(file_path)
. Biz işteyken, tüm fonksiyon basitleştirilebilir return file_path and os.path.isfile(file_path)
.
return x
durumunda if (x)
. Python boş bir dize yanlış düşünür, bu durumda bool yerine boş bir dize döndürüyoruz. Bu işlevin amacı daima bool döndürmektir.
x
olduğu os.path.isfile(..)
zaten bool oluyor böylece.
os.path.isfile(None)
bir istisna ortaya çıkarır bu yüzden if onay ekledi. Muhtemelen sadece bir deneyin / dışında sarmak olabilir ama bu şekilde daha açık olduğunu hissettim.
return file_path and os.path.isfile(file_path)
İşte Linux komut satırı ortamı için 1 satırlı bir Python komutu. Böyle sıcak bir Bash adamı olmadığım için bu ÇOK HANDY buluyorum.
python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"
Umarım bu yardımcı olur.
[ -f "${file}" ] && echo "file found" || echo "file not found"
(ki aynıdır if [ ... ]; then ...; else ...; fi
).
Python'un "OS" kütüphanesini kullanabilirsiniz:
>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt")
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False
os.path.exists
dizinler gibi dosya olmayan şeyler için true değerini döndürür. Bu yanlış pozitifler verir. Önerilen diğer yanıtlara bakın os.path.isfile
.
exists
sorun olmaz. Hedef, muhtemelen var olan bir dosyayı açmanın güvenli olup olmadığını belirlemekse, eleştiri haklıdır ve var olmak yeterince kesin değildir. Ne yazık ki, OP hangi hedefin hangisi olduğunu belirtmiyor (ve muhtemelen daha fazla yapmayacak).
Try deyimini kullanmadan bir dosyanın var olup olmadığını nasıl kontrol ederim?
2016'da, bu hala hem bir dosyanın hem de bir dosya olup olmadığını kontrol etmenin en kolay yoludur:
import os
os.path.isfile('./file.txt') # Returns True if exists, else False
isfile
aslında sadece dahili olarak kullanılan os.stat
ve stat.S_ISREG(mode)
altındaki bir yardımcı yöntemdir . Bu os.stat
, dosyalar, dizinler, soketler, arabellekler ve daha fazlası hakkında ayrıntılı bilgi sağlayacak alt düzey bir yöntemdir. Os.stat hakkında daha fazla bilgi burada
Not: Ancak, bu yaklaşım dosyayı hiçbir şekilde kilitlemez ve bu nedenle kodunuz "kullanım zamanı kontrol zamanı " ( TOCTTOU ) hatalarına karşı savunmasız hale gelebilir .
Bu nedenle, istisnaları yükseltmek, programınızdaki akış kontrolü için kabul edilebilir ve Pythonic bir yaklaşım olarak kabul edilir. Ve kişi eksik dosyaları if
ifadelerden ziyade IOErrors ile ele almalıdır ( sadece bir tavsiye ).
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)
ise dönecektirTrue