Bir dosyanın istisnasız olup olmadığını nasıl kontrol edebilirim?


5605

İfadeyi kullanmadan bir dosyanın var olup olmadığını nasıl kontrol ederim try?


2
Bu LBYL tartışmasına karşı klasik EAFP gibi görünüyor, örneğin bu ilgili soruya bakın: stackoverflow.com/questions/1835756/using-try-vs-if-in-python
matth

Ayrıca, diskte mevcut olup olmadığını (doğrudan veya sembolik bir bağlantı olarak) bilmek, ondan okuyabiliyorsanız veya üzerine yazabilirseniz de önemlidir.
Thorbjørn Ravn Andersen

Yanıtlar:


5153

Eğer kontrol etmenizin nedeni böyle bir şey yapabilmenizse if file_exists: open_it(), onu tryaç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 Trueyolu 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, pathlibmodül nesne yönelimli bir yaklaşım sunar ( pathlib2Python 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 Pathnesnenin 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 tryblokta da kullanabilirsiniz :

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

40
ilk açıklama ile ilgili olarak (eğer açmadan önce kontrol edin "deneyin" kullanın) 'a' modu mevcut olmadığından daha önce var olduğundan emin olmak için açmak istediğinizde maalesef bu çalışmaz.
makapuf

6
Bunun FileNotFoundErrorPython 3'te tanıtıldığına dikkat edin. Python IOErrorFileNotFoundError
2.7'nin

7
@makapuf "Güncelleme" ( open('file', 'r+')) için açıp sonuna kadar arayabilirsiniz.
kyrill

2
@kyrill sonuna kadar aç ve ara, eklenmek üzere aç ile aynı şey değildir (en azından posix sistemlerinde). "ekleme modu", dosya açıldığında ve yazma gerçekleştiğinde arasında başka değişiklikler olsa bile, dosyanın sonuna doğru her zaman doğru şekilde yazacaktır. Yazma / güncelleme için açma ve sonuna kadar arama, birden çok şey aynı dosyaya aynı anda yazmaya çalıştığında dosya verilerinin bozulmasına neden olabilir. Ne yazık ki, dosyanın ilk var olmasını sağlarken ekleme için açmanın tek yarış koşulu için güvenli yolun bunun yerine daha düşük düzeyli os.open () yordamlarını kullanmak olduğuna inanıyorum (O_CREAT olmadan O_APPEND).
Foogod

1
@LorinczyZsigmond, uygulamaya bağlı bir davranışa benziyor. Bir kaynağı paylaşmak ister misiniz?
kyrill

2111

Sen var os.path.existsfonksiyonu:

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

Bu Truehem 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.


965

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

623
import os.path

if os.path.isfile(filepath):

320

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

60
bazıları gereksiz olan birden fazla koşula sahip olmak daha az açık ve açıktır.
wim

10
Ayrıca gereksizdir. Dosya yoksa, os.access()false değerini döndürür.
user207421 13:01

9
@EJP Linux'ta dosyalar bulunabilir, ancak erişilemez.
e-info128

8
sizden beri , zaten bir parçası olduğu import osiçin import os.pathtekrar 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.pathosos.accessos.R_OK
Jester

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

2
Genellikle, değişkenleri yöntem adlarıyla aynı şekilde adlandırmak iyi bir uygulama değildir.
Homunculus Reticulli

245

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 :

  1. Dosyayı kontrol et ( tartışmalı : ayrıca klasör ("özel" dosya)?)
  2. Kullanmayın deneyin / hariç / else / nihayet blokları

Olası çözümler :

  1. [Python 3]: o. Yol. Varlığından ( yol ) (ayrıca gibi diğer fonksiyon aile üyelerini kontrol os.path.isfile, os.path.isdir, os.path.lexistsbiraz farklı davranışlar için)

    os.path.exists(path)

    Dönüş Trueise yol , varolan bir yola veya açık dosya tanımlayıcı karşılık gelir. FalseBozuk 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 ()

    • Yolları ele almak için daha ince (ve daha fazla python ic) bir yol, ancak
    • 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
  2. [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.

  3. Dosya sistemi geçiş işlevleri (ve eşleşen öğeler için sonuçları arayın)


    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.

  4. [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 )

    • kullanıcı izinleri , dokümanın belirttiği gibi "görünürlük" dosyasını kısıtlayabilir:

      ... ç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 :

    • Her ne kadar iyi bir uygulama olmasa da os.F_OK, çağrıda kullanıyorum , ama bu sadece netlik için (değeri 0 )
    • _Waccess kullanıyorum böylece aynı kod Python3 ve Python2 üzerinde çalışır ( aralarındaki unicode ilgili farklılıklar rağmen )
    • Bu çok spesifik bir alanı hedeflese de, önceki cevapların hiçbirinde bahsedilmemişti


    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 .

      • Ana (mevcut) program ( python ) libc ile bağlantılıdır , bu yüzden sembolleri ( erişim dahil ) yüklenecektir
      • Main , Py_Main ve (tümü) diğerleri gibi işlevler mevcut olduğundan, bu işlem dikkatli bir şekilde gerçekleştirilmelidir ; onları çağırmak felakete neden olabilir (mevcut programda)
      • Bu, Win için de geçerli değildir (ancak msvcrt.dll , varsayılan olarak % PATH% içinde bulunan "% SystemRoot% \ System32" içinde yer aldığı için bu kadar büyük bir anlaşma değildir ). Bir şeyleri daha ileri götürmek ve Win üzerinde bu davranışı çoğaltmak istedim (ve bir yama gönderin), ancak ortaya çıktığı gibi, [MS.Docs]: GetProcAddress işlevi , birisi ana yürütülebilir dosya işlevlerini bildirmedikçe yalnızca dışa aktarılan sembolleri "görür" olarak (Dünya'da neden düzenli kişi bunu yapar?), ana program yüklenebilir ama hemen hemen kullanılamaz__declspec(dllexport)
  5. 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.

  6. 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ç :

  • Do kullanım deneyin / hariç / else / nihayet onlar seni yaramaz bir dizi sorun haline çalışan önleyebilir çünkü bloklar. Düşünebileceğim bir karşı örnek performanstır: bu tür bloklar pahalıdır, bu yüzden onları saniyede yüz binlerce kez çalıştırması gereken kodlara yerleştirmemeye çalışın (ancak çoğu durumda disk erişimi içerdiğinden, durum böyle olmayacak).

Son not (lar) :

  • Güncel tutmaya çalışacağım, herhangi bir öneri bekliyoruz, cevabın ortaya çıkmasına yardımcı olacak her şeyi dahil edeceğim

3
Bu ifadeyi açıklayabilir misiniz? "Her ne kadar iyi bir uygulama olmasa da, çağrıda os.F_OK kullanıyorum, ama bu sadece netlik için (değeri 0)"
sk8asd123

6
@ sk8asd123: Bir yorumda bunu yapmak biraz zor: genellikle, birlikte geldikleri işlevlerle sabitleri kullanmak en iyisidir. Bu, aynı sabiti tanımlayan birden fazla modülle çalışırken geçerlidir, çünkü bazıları güncel olmayabilir ve işlevlerin ve sabitlerin senkronize olması en iyisidir. (Fonksiyonları doğrudan çağırarak) ctypes ile çalışırken sabit ( MSDN'den ) tanımlanmış olmalı veya hiç bir sabit kullanmamalıyım. Bu sadece benim kullandığım bir rehber,% 99.9'da muhtemelen hiçbir şey fark etmiyor (işlevsel olarak).
CristiFati

3
@CristiFati: 3.6'dan itibaren glob.iglob(ve glob.globde) 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, globherhangi 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.isdirya daos.path.lexists (yolun bitip bitmediğine bağlı olarak) basitleştirir/ .
ShadowRanger

3
Yorumumun bu ikinci kısmı (joker karakterli olmayan globbing aslında klasörü yinelemez ve asla sahip değildir), sorunun mükemmel etkili bir çözümü anlamına gelir (doğrudan aramadan daha yavaş os.path.isdirveya os.path.lexistPython 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).
ShadowRanger

154

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

17
Dosyaya erişmeyi düşündüğünüz sürece , programınızın nasıl oluşturulduğuna bakılmaksızın yarış durumu mevcuttur . Programınız, bilgisayardaki başka bir işlemin dosyayı değiştirmediğini garanti edemez. Eric Lippert'in ekzojen bir istisna olarak ifade ettiği şey budur . Önceden dosyanın varlığını kontrol ederek bundan kaçınamazsınız.
Isaac Supeene

@IsaacSupeene En iyi uygulama, (dosya) işleminin penceresini mümkün olduğunca küçük hale getirmek ve ardından uygun bir istisna işlemesi
yapmaktır

145

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/exceptDosyaları 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

124

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:


3
Lütfen beyanınızı desteklemek için daha iyi kaynaklar ekleyin.
BlueTrin

11
Belirtilen Yarış Koşullarından Kaçınma (apple dev desteği) bağlantısı cevabınızı desteklemiyor. Yalnızca, kısıtlı izinlerle geçici dosyaları / dizinleri düzgün bir şekilde korumasız alan, kötü tasarlanmış işletim sistemlerinde hassas bilgiler içeren geçici dosyaların kullanılmasıyla ilgilidir. Kullanmak zaten bu sorunun try...exceptçözülmesine yardımcı olmaz.
jstine

Bu yöntemle ilgili sorun, varolmayan dosyaya bağlı olarak önemli bir kod parçanız varsa, 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.)
Camion

119

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_fileyö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 pathlib2veya başka kontrol isfilegelen os.pathmodü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 tryuygulamasında her yerde kullanır .

Python tryher 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.

Daha uzun, çok daha bilgiçliksel cevap

Python 3.4'ten beri kullanılabilir, içindeki yeni Pathnesneyi kullanın pathlib. Bunun .existsdoğ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, NamedTemporaryFilekapatı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_filekullanı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

Yarış Koşulları: Neden denemeyi seviyoruz

Biz mi tryo 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 .trysuppress

Deneme bildirimi olmadan yarış koşullarından kaçınma: suppress

Python 3.4 bize suppressdaha ignoreaz 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 tryifadeyi 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 tryistek 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

"Denemeden" sorusunu karşılamayan diğer seçenekler:

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()ve isfile()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 OSErrorve 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.accessiç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 cevabın eleştirisi:

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 ( KeyboardInterruptve 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.


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

İç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.


9
Bu cevap yanlış. os.path.existsdizinler 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.
Chris Johnson

84

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:

resim açıklamasını buraya girin

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

72

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

3
Sorabilir miyim: Bu kontrol için python3'teki 'os' modülü yerine 'pathlib' modülünü kullanmanın avantajı nedir?
Joko

3
pathlibpython'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.
KaiBuxe

65

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.


3
Bu cevap yanlış. os.path.existsdizinler 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.
Chris Johnson

6
Üçüncü örneğinizde, filepathdoğ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...exceptblokta yapmanız gerekir .
spektrumlar

1
İkinci örnekte, Windows azından, bir alacak OSErroreğ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. "
Tom Myddeltyn

@TomMyddeltyn: Python 3.3'tenos.replace itibaren, hedef dosyanın sessiz bir şekilde değiştirilmesini sağlar ( os.renameLinux'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.
ShadowRanger

On renameÖrneğin: Hala ile yapılmalıdır try/ ' except. os.rename(veya os.replacemodern 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
ShadowRanger

59

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.


18
Orijinal soru kullanmayan bir çözüm isteditry
rrs

5
Bu cevap OP'nin noktasını kaçırıyor. Bir dosyanın var olup olmadığını kontrol etmek, dosyayı açıp açamayacağınızı kontrol etmekle aynı şey değildir. Bir dosyanın bulunduğu durumlar olacaktır, ancak çeşitli nedenlerle dosyayı açamazsınız.
Chris Johnson

51

Her zaman tryve exceptifadeleri kullanmanızı öneririm , işte size birkaç olasılık (kişisel favorim kullanıyor os.access):

  1. 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 trybö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
  2. 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
  3. Kullanım os.access(path, mode):

    Bu, dosyaya erişiminizin olup olmadığını kontrol eder. İzinleri kontrol eder. Osppy belgelerine dayanarak, yazarak os.F_OKyolun 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 deniedya 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! :)


51

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

37

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 .


9
Bu cevap yanlış. os.path.existsdizinler 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.
Chris Johnson

yanlış pozitif sorunu da var.
Zorglub29

docs.python.org/3/library/os.path.html#os.path.exists chris >> os.path.exists (yol)> Yukarıdaki ifadeye yol varolan bir yolu veya açık yolu gösteriyorsa True döndür dosya tanıtıcı. Bozuk sembolik bağlantılar için False değerini döndürür. Bazı platformlarda, yol fiziksel olarak var olsa bile, istenen dosyada os.stat () yürütülmesine izin verilmezse bu işlev Yanlış döndürebilir. 3.3 sürümünde değiştirildi: yol artık bir tamsayı olabilir: Açık bir dosya tanımlayıcı ise True döndürülür, aksi halde False. 3.6 sürümünde değiştirildi: Yol benzeri bir nesneyi kabul eder.
JayRizzo

36

Ayrıca os.access():

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

Varlık R_OK, W_OKve X_OKizinleri test etmek için bayraklar ( doc ).


20
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.

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


3
OP bir dosyanın var olup olmadığını nasıl kontrol edeceğini sordu. Bir dosyanın mevcut olması mümkündür ancak dosyayı açamamanız mümkündür. Bu nedenle, dosyanın var olup olmadığını kontrol etmek için bir dosyayı proxy olarak açmanın doğru olmadığı: yanlış negatifleri olacaktır.
Chris Johnson

19

Başka amaçlar için zaten numpy ithal sonra gibi diğer kütüphaneleri ithal etmek gerek yoktur pathlib, os, pathsvb

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

Bu, varlığına bağlı olarak doğru veya yanlış döndürür.


18

Brian'ın önerisini olmadan yazabilirsiniz try:.

from contextlib import suppress

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

suppressPython 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

17

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 Popenerişmek için kullanır find. Ancak, Windows kullanıyorsanız, findverimli bir dosya sistemi yürütücüsüyle çoğalır .

Kodun kendisi bir tryblok kullanmaz … işletim sistemini belirlemek ve böylece sizi "Unix" findtarzı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


17

Dosya veya dizini kontrol et

Bu üç yolu takip edebilirsiniz:

Not1: os.path.isfileYalnı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.existsHem 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.PathYöntemi (Python dahil 3+, Python 2 pip ile kurulabilir)

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

16

Diğer cevaplara tam olarak yansıtılmayan bir küçük değişiklik daha eklemek.

Bu, file_pathvarlık Noneveya 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):

3
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).
Shahbaz

Sen ile dikkatli olmak zorunda return xdurumunda 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.
Marcel Wilson

1
Doğru. Ancak bu durumda, xolduğu os.path.isfile(..)zaten bool oluyor böylece.
Shahbaz

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.
Marcel Wilson

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

15

İş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.


6
Bash'ta tek satırlık kontrol: [ -f "${file}" ] && echo "file found" || echo "file not found"(ki aynıdır if [ ... ]; then ...; else ...; fi).
flotzilla

12

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

5
Bu cevap yanlış. os.path.existsdizinler 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.
Chris Johnson

@Chris Johnson, os.path.exists () işlevi, sistemde bir yol olup olmadığını kontrol eder. PATH bir DIRECTORY veya FILE olabilir. Her iki durumda da iyi çalışacaktır. Lütfen bir örnekle deneyin
Pradip Das

Yani, bu cevap işe yarıyor. Harika. Iff yol bir dosya değil. Sorunun konusu bu muydu? Hayır.
Debosmit Ray

Değişir. Bir "dosyanın" varlığını belirleme amacı, yolun zaten var olup olmadığını bulmaksa (ve bu nedenle, yeni bilgilerin silinmeden yeni verilerin depolanabileceği bir yol değilse), existssorun 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).
starturtle

12

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

isfileaslında sadece dahili olarak kullanılan os.statve 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ı ififadelerden ziyade IOErrors ile ele almalıdır ( sadece bir tavsiye ).


9
import os.path

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

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

isReadableFile(path, fileName)

@ j6m8 evet, dosyaya \ program \ thread tarafından ulaşılabilir ve okunabilir isReadableFile(path,fileName)ise dönecektirTrue
Khaled.K
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.