Cum pot vedea dacă un fișier există sau nu, fără a utiliza încerc
declarație?
Dacă motivul pentru care ai're verificarea este astfel încât să puteți face ceva de genul daca file_exists: open_it()
, l's mai sigur de a utiliza o "încerca" în jurul valorii de încercarea de a-l deschide. Verificarea și apoi deschiderea riscuri fișier care a fost șters sau mutat sau ceva în între, atunci când a verifica și atunci când încercați să-l deschidă.
Daca're nu intenționează să deschideți fișierul imediat, puteți utiliza os.calea.isfile
import os.path
os.path.isfile(fname)
dacă aveți nevoie pentru a fi sigur că-l's un fișier.
Începând cu Python 3.4, pathlib
module oferă o abordare orientată spre obiect (portate în `pathlib2 în Python 2.7):
from pathlib import Path
my_file = Path("/path/to/file")
if my_file.is_file():
# file exists
Pentru a verifica un director, nu:
if my_file.is_dir():
# directory exists
Pentru a verifica dacă o "Cale" obiectul există independent de faptul dacă este un fișier sau director, utilizați există()
:
if my_file.exists():
# path exists
Puteți folosi, de asemenea, rezolva(strict=True)
in o "încerca" bloc:
try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
Ai [os.calea.există
](https://docs.python.org/2/library/os.path.html#os.path.exists funcția):
import os.path
os.path.exists(file_path)
Acesta returnează "Adevărat" atât pentru fișiere și directoare, dar puteți folosi în loc de
os.path.isfile(file_path)
pentru a testa dacă-l's un fișier special. Rezultă legături simbolice.
Spre deosebire de isfile()
, există()
va returna "True" pentru directoare.
Deci, în funcție de dacă doriți doar simplu fișiere sau directoare, ai'll folosesc isfile () " sau " există()`. Aici este un simplu REPL de ieșire.
>>> print os.path.isfile("/etc/password.txt")
True
>>> print os.path.isfile("/etc")
False
>>> print os.path.isfile("/does/not/exist")
False
>>> print os.path.exists("/etc/password.txt")
True
>>> print os.path.exists("/etc")
True
>>> print os.path.exists("/does/not/exist")
False
Folosi os.calea.isfile()
cu os.acces()
:
import os
import os.path
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"
Deși aproape orice mod posibil de a fost enumerate în (cel puțin unul) existente răspunsuri (de exemplu, Python 3.4 anumite chestii fost adăugat), am'll încerca să group totul împreună. Notă: fiecare bucată de Python biblioteca standard de cod pe care am'm a merge la post, aparține versiune 3.5.3. Formularea problemei:
sistem de operare.calea.există(calea)
Returna "True" dacă calea se referă la un traseu existent sau un fișier deschis descriptor. Returneaza "False" pentru broken link-uri simbolice. Pe unele platforme, această funcție poate returna "Fals" dacă permisiunea nu este acordat pentru a executa os.stat() pe fișierul solicitat, chiar dacă path există în mod fizic. Toate bune, dar dacă după import copac:
os.calea
- posixpath.py (ntpath.py) os.calea.isfile
).
1.1. [Python 3]: Cale.este_file() return False
Folosind scandir() în loc de listdir() poate crește în mod semnificativ performanța de cod care trebuie, de asemenea, tipul de fișier sau fișier atribut informații, pentru că os.DirEntry obiecte expune aceste informații dacă sistemul de operare oferă atunci când scanați un director. Toate os.DirEntry metode poate efectua un apel de sistem, dar is_dir() și is_file(), de obicei, nevoie doar de un apel de sistem pentru link-uri simbolice; os.DirEntry.stat() necesită întotdeauna un apel de sistem pe Unix, dar necesită doar un singur pentru link-uri simbolice pe Windows.
os.listdir
(sistem de operare.scandir
atunci când sunt disponibile) glob.glob
) os.listdir
...testa dacă invocarea utilizatorul a specificat acces la cale. modul ar trebui să fie F_OK pentru a testa existența calea...
os.acces("/tmp", os.F_OK)
De când am lucra, de asemenea, în C, am utilizat această metodă la fel de bine pentru că sub capota, se solicită nativ APIs (din nou, prin "${PYTHON_SRC_DIR}/Module/posixmodule.c"), dar, de asemenea, deschide o poarta pentru o eventuală erori de utilizator, și-l's nu fi Pythonic și alte variante. Deci, ca @AaronHall subliniat, pe bună dreptate, don't folosi decât dacă știi ce ai de're face:
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v. 1900 64 de biți (AMD64)] pe win32 Tip "ajutor", "autor", "credite" sau "licență" pentru mai multe informații.
import os, ctypes ctypes.CDLL("msvcrt dll")._waccess(u"C:\Windows\System32\cmd.exe", os.F_OK) Zero ctypes.CDLL("msvcrt dll")._waccess(u"C:\Windows\System32\cmd.exe.notexist", os.F_OK) -1 Note:
Python 3.5.2 (implicit, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] pe linux Tip "ajutor", "autor", "credite" sau "licență" pentru mai multe informații.
import os, ctypes ctypes.CDLL("/lib/x86_64-linux-gnu/libc.deci.6").acces(b"/tmp", os.F_OK) Zero ctypes.CDLL("/lib/x86_64-linux-gnu/libc.deci.6").acces(b"/tmp.notexist", os.F_OK) -1 Note:
ctypes.CDLL(Nici unul).acces(b"/tmp", os.F_OK)
). În conformitate cu [man7]: DLOPEN(3): Dacă numele fișierului este NUL, apoi a revenit mânerul este pentru principalele program. Când a dat la dlsym(), acest mâner provoacă o căutare pentru un simbol în programul principal, urmat de toate în comun obiectele încărcate la program de pornire, și apoi toate în comun obiecte încărcate de dlopen() cu steagul RTLD_GLOBAL**.
__declspec(dllexport)
(de ce pe Pământ regulate persoană ar face asta?), programul principal este reîncărcabil, dar destul de mult inutilizabile (py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; imprimare(os.sistemul('dir /b \"C:\Windows\System32\cmd.exe\" > nul 2>&1'))" Zero (py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; imprimare(os.sistemul('dir /b \"C:\Windows\System32\cmd.exe.notexist\" > nul 2>&1'))" Unul
[cfati@cfati-ubtu16x64-0:~]> python3 -c "import os; imprimare(os.sistemul('e \"/tmp\" > /dev/null 2>&1'))" Zero [cfati@cfati-ubtu16x64-0:~]> python3 -c "import os; imprimare(os.sistemul('e \"/tmp.notexist\" > /dev/null 2>&1'))" Cinci sute doisprezece Linia de fund:
Aceasta este cea mai simplă modalitate de a verifica dacă un fișier există. Doar pentru fișierul nu exista cand ai verificat nu't garantie care va fi acolo atunci când aveți nevoie să-l deschidă.
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+ are un obiect-orientate spre calea modulul: pathlib. Folosind acest nou modul, puteți verifica dacă există un fișier de genul asta:
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
Puteți (și, de obicei, ar trebui să) încă mai folosesc un try/cu excepția bloca la deschiderea fișierelor:
try:
with p.open() as f:
# do awesome stuff
except OSError:
print('Well darn.')
La pathlib modulul are o mulțime de lucruri interesante în ea: convenabil expandarea, verificarea fișier's proprietarului, mai ușor calea aderării, etc. L's valoare de verificat. Daca're pe un mai vechi Python (versiunea 2.6 sau mai târziu), puteți instala încă pathlib cu pip:
# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2
Apoi importați-l după cum urmează:
# Older Python versions
import pathlib2 as pathlib
Preferă să încerce o declarație. L's a considerat mai bine stilul și evită condițiile de rasă.
Don't ia cuvântul meu pentru asta. Nu's o multime de suport pentru această teorie. Aici's un cuplu:
Stil: Secțiunea "Manipulare condiții neobișnuite" de http://allendowney.com/sd/notes/notes11.txt
Cum pot verifica dacă un fișier există, folosind Python, fără a utiliza o încercare declarație?
Acum disponibil începând cu Python 3.4, import și instantia o "Cale" obiect cu numele de fișier, și verificați
is_file
metoda (rețineți că acest lucru returnează True pentru legături simbolice arătând spre regulat fișierele la fel de bine):
>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False
Daca're pe Python 2, puteți backport la pathlib modulul de la pypi, [pathlib2
][1], sau în caz contrar, verificați isfile "de la" sistemul de operare.calea
module:
>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False
Acum cele de mai sus este, probabil, cel mai pragmatic răspuns direct aici, dar nu's posibilitatea unei stări (în funcție de ceea ce're încercarea de a realiza), și faptul că în aplicare de bază utilizează un "încerca", dar Python folosește "încerca" peste tot în punerea sa în aplicare. Deoarece Python folosește "încerca" peste tot, nu's nici un motiv pentru a evita o punere în aplicare pe care le folosește. Dar restul de acest răspuns încearcă să ia în considerare aceste limitări.
Disponibil din Python 3.4, utilizați noul "Cale" obiect în pathlib
. Rețineți că.există` nu este destul de corect, pentru că directoarele nu sunt fișiere (cu excepția cazului în unix sensul că totul este un fișier).
>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True
Deci, avem nevoie pentru a folosi is_file`:
>>> root.is_file()
False
Aici's a ajuta pe is_file`:
is_file(self)
Whether this path is a regular file (also True for symlinks pointing
to regular files).
Deci sa's a obține un fișier care știm că este un fișier:
>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True
În mod implicit, NamedTemporaryFile
șterge fișierul atunci când sunt închise (și se va închide automat atunci când nu mai există referințe la acesta).
>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False
Dacă sapi în [aplicare][2], deși,'ll vedea că is_file
foloseste "încerca":
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
Ne place "încerca" pentru că se evită condițiile de rasă. Cu "încerca", pur și simplu încercarea de a citi fișierul dvs., mă așteptam să fie acolo, și dacă nu, te prinde excepție și de a efectua orice comportament de rezervă sens. Dacă doriți să verificați că există un fișier înainte de a încerca să-l citească, și s-ar putea fi ștergerea și atunci ați putea fi utilizați mai multe fire sau procese, sau un alt program știe despre dosarul și l-ar putea șterge - te-ai risca o stări de dacă tu a verifica că există, pentru că sunt apoi curse să-l deschidă înainte de stare (existență) modificări. Condițiile de rasă sunt foarte greu de corectat deoarece nu's-o foarte mică fereastră în care acestea pot provoca programul tău de a eșua. Dar dacă aceasta este motivația ta, ai poate ia valoarea o "încerca" declarație prin utilizarea `a suprima context manager.
suprima
Python 3.4 ne dă [a suprima
][3] contextul manager (anterior [ignore
][4] contextul manager), care are semantic exact același lucru în mai puține linii, în timp ce, de asemenea, (cel puțin superficial) întâlnire originale cere pentru a evita o "încerca" declarație:
from contextlib import suppress
from pathlib import Path
Utilizare:
>>> with suppress(OSError), Path('doesnotexist').open() as f:
... for line in f:
... print(line)
...
>>>
>>> with suppress(OSError):
... Path('doesnotexist').unlink()
...
>>>
Pentru mai devreme Pitoni, ai putea rula propriul dvs. de `a suprima, dar fără o "încerca" va fi mai detaliată decât cu. Eu nu cred aceasta este, de fapt, singurul răspuns pe care nu - 't folosi "încerca" la orice nivel în Python care pot fi aplicate înainte de Python 3.4 deoarece foloseste un context manager în loc:
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)
Poate că mai ușor cu o încerca:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
isfile
import os
os.path.isfile(path)
de [documente][5]:
os.calea.isfile(cale)
Return True dacă calea este un existent fișier obișnuit. Acest lucru rezultă simbolic link-uri, astfel încât ambeleislink () " și " isfile()
poate fi valabil și pentru aceeași cale. Dar dacă examinăm [sursa][6] din această funcție, nu'll vedea că de fapt nu utilizați o încercare declarație:Aceasta urmează link-uri simbolice, astfel încât ambele islink() și isdir() poate fi adevărat
pentru aceeași cale pe sistemele care acceptă legături simbolice
def isfile(calea): """a Testa dacă un drum este un fișier obișnuit""" încercați: st = os.stat(calea) cu excepția sistemului de operare.eroare: return False reveni imediat.S_ISREG(st.st_mode)
>>> OSError is os.error
True
Toate l's faci este dat cale de a vedea dacă poate obține statistici pe ea, prinderea OSError
și apoi verificarea dacă-l's un fișier dacă nu m't ridica o excepție.
Dacă ai de gând să faci ceva cu dosarul, mi-ar sugera în mod direct se încearcă cu o încerca-cu excepția pentru a evita o condiție de rulare:
try:
with open(path) as f:
f.read()
except OSError:
pass
sistemul de operare.de acces Disponibil pentru Unix și Windows este sistemul de operare.acces`, dar pentru a utiliza, trebuie să treacă steaguri, și nu face distincția între fișiere și directoare. Acest lucru este mai mult folosit pentru a testa dacă adevăratul invocarea utilizatorul are acces într-o elevată privilegiul de mediu:
import os
os.access(path, os.F_OK)
De asemenea, suferă de aceleași stări de probleme ca isfile
. De [documente][7]:
Notă: Folosind access() pentru a verifica dacă un utilizator este autorizat, de exemplu de a deschide un fișier de fapt, înainte de a face astfel încât folosind open() creează o gaură de securitate, deoarece utilizatorul ar putea exploata interval de timp scurt între verificarea și deschideți fișierul pentru a-l manipuleze. E de preferat să folosiți EAFP tehnici. De exemplu:
dacă sistemul de operare.acces("myfile", os.R_OK): deschis("myfile"), ca fp: return fp.read() întoarcere "unele date implicit"
este mai bine scris ca:
încercați: fp = open("myfile") cu excepția IOError ca e: dacă e.errno va fi == errno va fi.EACCES: întoarcere "unele date implicit"
Nu o permisiunea de eroare.
ridica altcineva: cu fp: return fp.read() Evitați utilizarea
os.acces
. Este un nivel scăzut funcție care are mai multe oportunități pentru utilizator eroare decât obiecte de nivel superior și funcțiile discutate mai sus.Critica un alt răspuns:
Un alt răspuns spune asta despre
os.acces
: Personal, prefer asta pentru că sub capota, acesta apeluri Api-uri native (prin intermediul "${PYTHON_SRC_DIR}/Module/posixmodule.c"), dar, de asemenea, deschide o poarta pentru posibilele erori de utilizator, și-l's nu ca Pythonic și alte variante: Acest răspuns spune că preferă un non-Pythonic, predispuse la erori de metodă, cu nici o justificare. Se pare că pentru a încuraja utilizatorii să folosească low-level Api-uri, fără a le înțelege. De asemenea, creează un context manager care, prin necondiționat revenind "Adevărat", permite tuturor Excepțiilor (inclusivKeyboardInterrupt " și " SystemExit
!) pentru a trece în tăcere, care este o modalitate buna de a ascunde bug-uri. Acest lucru pare a încuraja utilizatorii să adopte practicile săraci.
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!"
Importul de os
face mai ușor pentru a naviga și de a efectua acțiuni standard, cu sistemul de operare.
Pentru referință, de asemenea, a se vedea Cum pentru a verifica dacă există un fișier folosind Python?
Dacă ai nevoie de operațiuni la nivel înalt, utilizat shutil
.
Testarea pentru fișiere și foldere cu os.calea.isfile()
, os.calea.isdir () " și " sistem de operare.calea.există()
Presupunând că "calea" este o cale validă, acest tabel arată ce este returnată de către fiecare funcție pentru fișiere și foldere:
De asemenea, puteți testa dacă un fișier este un anumit tip de fișier, folosind os.calea.splitext()
pentru a obține prelungirea (dacă nu't știu deja)
>>> 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
În 2016 cel mai bun mod este încă utilizați os.calea.isfile
:
>>> os.path.isfile('/path/to/some/file.txt')
Sau în Python 3 puteți folosi pathlib`:
import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
...
Nu't pare ca acolo's o semnificativă diferență funcțională între/în afară și isfile()
, așa că ar trebui să utilizați unul care are sens.
Dacă doriți să citiți un fișier, dacă există, nu
try:
f = open(filepath)
except IOError:
print 'Oh dear.'
Dar dacă ai vrut doar pentru a redenumi un fișier dacă acesta există, și, prin urmare, nu't nevoie pentru a deschide, nu
if os.path.isfile(filepath):
os.rename(filepath, filepath + '.old')
Dacă doriți să scrieți într-un fișier, dacă nu't există, nu
# 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'
Dacă aveți nevoie de fișierul de blocare, care's o chestiune diferită.
Ai putea încerca acest lucru (mai sigur):
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 ar fi:
([errno va fi 2] Nu există un astfel de fișier sau director: 'orice.txt')
Apoi, în funcție de rezultat, programul poate fugi de acolo sau poate codul pentru a opri, dacă doriți.
Deși mereu am recomandăm să utilizați "încerca" și în afară de declarații, aici sunt câteva posibilități pentru tine (favoritul meu personal este folosind os.acces
):
Deschiderea fișierului va fi întotdeauna verifică existența fișierului. Puteți face o funcție doar astfel:
def File_Existence(filepath): f = open(filepath) return True
Daca's False, se va opri execuția cu un unhanded IOError sau OSError în versiunile ulterioare de Python. Pentru a prinde o excepție, trebuie să utilizați o încercare cu excepția clauzei. Desigur, puteți întotdeauna utilizați un "încerca" cu excepția declarația ca deci (datorită hsandt pentru a mă face să cred):
def File_Existence(filepath): încercați: f = open(filepath) cu excepția IOError, OSError: # Notă OSError este pentru mai târziu versiuni de Python return False
return True
Acest lucru va verifica existența a ceea ce ai specificat. Cu toate acestea, se verifică pentru fișiere și directoare, deci feriți-vă despre modul de utilizare.
import os.calea
sistem de operare.calea.există("acest/e/o/director de") Adevărat sistem de operare.calea.există("acest/e/o/fișier.txt") Adevărat sistem de operare.calea.există("nu/o/director de") False
Acest lucru va verifica dacă aveți acces la fișier. Se va verifica pentru permisiuni. Pe baza os.py documentația, tastarea în os.F_OK
, se va verifica existența calea. Cu toate acestea, folosind acest lucru va crea o gaură de securitate, ca cineva poate ataca fișierul dvs. folosind timp între verificarea permisiunilor și deschiderea fișierului. Tu ar trebui să meargă direct la deschiderea fișierului în loc de a verifica permisiunile acestuia. (EAFP vs LBYP). Daca're nu se va deschide fișierul după aceea, și numai verificarea existenței sale, atunci puteți folosi acest.
Oricum, aici:
import os sistem de operare.acces("/e/o/fișier.txt", os.F_OK) Adevărat
Ar trebui să menționeze, de asemenea, că există două moduri în care nu va fi în măsură să verifice existența unui fișier. Fie problema va fi permission denied " sau " nu există un astfel de fișier sau director
. Dacă te prind o IOError
, stabilit IOError ca e
(cum ar fi prima mea opțiune), apoi tastați în print(e.args)
, astfel încât să puteți să sperăm determina problema. Sper că vă ajută! :)
Data:2017-12-04
Fiecare soluție posibilă a fost enumerate în alte răspunsuri.
Un intuitiv și discutabil modalitate de a verifica dacă există un fișier este următorul:
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')
Am făcut o exhaustivă cheatsheet pentru referință:
#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']}
Dacă fișierul este pentru deschiderea ai putea folosi una din următoarele tehnici:
>>> 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!')
UPDATE
Tocmai pentru a evita confuziile și se bazează pe răspunsuri am primit, răspunsul actual găsește fie un fișier sau un director cu numele dat.