Как проверить, существует ли файл, без использования try
утверждение?
Как проверить, существует ли файл без исключений?
Ответы (42)
Если причина, по которой вы проверяете, заключается в том, чтобы вы могли сделать что-то вроде if file_exists: open_it()
, безопаснее использовать try
вокруг попытки открыть его. При проверке и последующем открытии файл может быть удален или перемещен или что-то в этом роде между моментом проверки и попыткой его открытия.
Если вы не планируете открывать файл немедленно, вы можете использовать os.path.isfile
Вернуть
True
, если путь - существующий обычный файл. Это следует по символическим ссылкам, поэтому как islink (), так и isfile () может быть истинным для того же пути.
import os.path
os.path.isfile(fname)
если вам нужно быть уверенным, что это файл.
Начиная с Python 3.4, pathlib
module предлагает объект -ориентированный подход (перенесен на pathlib2
в Python 2.7):
from pathlib import Path
my_file = Path("/path/to/file")
if my_file.is_file():
# file exists
Чтобы проверить каталог, выполните:
if my_file.is_dir():
# directory exists
Чтобы проверить, существует ли объект Path
независимо от того, является ли он файлом или каталогом, используйте exists()
:
if my_file.exists():
# path exists
Вы также можете использовать resolve(strict=True)
в try
блоке:
try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
FileNotFoundError
был введен в Python 3. Если вам также необходимо поддерживать Python 2.7, а также Python 3, вы можете использовать вместо этого IOError
(которые FileNotFoundError
подклассы) stackoverflow.com/a/21368457/1960959
- person scottclowe; 29.03.2019
open('file', 'r+')
) и потом искать до конца.
- person kyrill; 30.04.2019
pathlib2
‹pathlib
? pathlib
для python3, верно? Я использовал pathlib2
, думая, что это лучше.
- person theX; 03.07.2020
'a'
.
- person hagello; 20.11.2020
У вас есть функция os.path.exists
:
import os.path
os.path.exists(file_path)
Это возвращает True
как для файлов, так и для каталогов, но вместо этого вы можете использовать
os.path.isfile(file_path)
чтобы проверить, является ли это конкретным файлом. Он следует символическим ссылкам.
В отличие от isfile()
, _ 2_ вернет True
для каталогов. Поэтому в зависимости от того, нужны ли вам только простые файлы или также каталоги, вы будете использовать isfile()
или exists()
. Вот простой вывод REPL:
>>> 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
Используйте os.path.isfile()
с 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.
- person user207421; 13.03.2018
import os
, вам не нужно снова import os.path
, поскольку он уже является частью os
. Вам просто нужно импортировать os.path
, если вы собираетесь использовать функции только из os.path
, а не из самого os
, чтобы импортировать меньшую вещь, но поскольку вы используете os.access
и os.R_OK
, второй импорт не нужен.
- person Jester; 24.08.2018
Хотя почти все возможные способы были перечислены в (по крайней мере, в одном из) существующих ответов (например, был добавлен конкретный материал для Python 3.4), я постараюсь сгруппировать все вместе.
Примечание: каждый фрагмент кода стандартной библиотеки Python, который я собираюсь опубликовать, принадлежит версии 3.5.3.
Описание проблемы:
- Проверить наличие файла (спорного: также папки ("особого" файла)?)
- Не используйте try / except / else strong > / finally блоки
Возможные решения:
[Python 3]: os.path. существует (путь) (также проверьте другие члены семейства функций, такие как
os.path.isfile
,os.path.isdir
,os.path.lexists
, на предмет немного отличающегося поведения)os.path.exists(path)
Вернуть
True
, если путь относится к существующему пути или дескриптору открытого файла. ВозвращаетFalse
для неработающих символических ссылок. На некоторых платформах эта функция может возвращатьFalse
, если не предоставлено разрешение на выполнение os. .stat () в запрошенном файле, даже если путь физически существует.Все хорошо, но если следовать дереву импорта:
os.path
- posixpath.py (ntpath.py)genericpath.py, строка ~ # 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
это просто блок try / except вокруг [Python 3]: os. stat (путь, *, dir_fd = None, follow_symlinks = True < / em>). Итак, ваш код попробуйте / за исключением бесплатен, но ниже в стеке кадров есть (по крайней мере) один такой блок. Это также относится к другим функциям (включая
os.path.isfile
).1.1. [Python 3]: путь. is_file ()
- Это более изящный (и в большей степени python ic) способ обработки путей, но
Под капотом он делает в точности то же самое (pathlib.py, строка ~ # 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]: с менеджерами контекста операторов. Или:
Создай:
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 ...)
И его использование - я воспроизведу поведение
os.path.isfile
(обратите внимание, что это просто для демонстрации, не пытайтесь писать такой код для производственной):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. подавить ( * исключения), который был специально разработан для выборочного подавления исключений.
Но они кажутся обертками над try / except / else / finally блокируется как [Python 3]: в инструкции with говорится:Это позволяет часто попробовать ... except ... finally шаблоны использования, которые необходимо инкапсулировать для удобного повторного использования.
Функции обхода файловой системы (и поиск в результатах совпадающих элементов)
[Python 3]: os. listdir (< em> path = '.') (или [Python 3]: os. scandir (path = '.') на Python v 3.5 strong> +, backport: [PyPI]: scandir)
Под капотом оба используют:
- Nix: [man7]: OPENDIR(3) / [man7]: READDIR(3) / [man7]: CLOSEDIR(3)
- Win: [MS .Docs]: функция FindFirstFileW / [MS.Docs]: функция FindNextFileW / [MS.Docs]: функция FindClose
через [GitHub]: python / cpython - (мастер) cpython / Modules / posixmodule .c
Использование scandir () вместо listdir () может значительно повысить производительность кода, которому также нужна информация о типе файла или атрибуте файла, поскольку объекты os.DirEntry предоставляют эту информацию, если операционная система предоставляет это при сканировании каталога. Все методы os.DirEntry могут выполнять системный вызов, но is_dir () и is_file () обычно требует системного вызова только для символьных ссылок; os.DirEntry.stat () всегда требует наличия системы вызывается в Unix, но требуется только одна для символических ссылок в Windows.
- [Python 3]: os.walk(top, topdown=True, onerror=None, followlinks=False)
- It uses
os.listdir
(os.scandir
when available)
- It uses
- [Python 3]: glob.iglob(pathname, *, recursive=False) (or its predecessor:
glob.glob
)- Doesn't seem a traversing function per se (at least in some cases), but it still uses
os.listdir
- Doesn't seem a traversing function per se (at least in some cases), but it still uses
Поскольку они перебирают папки (в большинстве случаев), они неэффективны для нашей проблемы (есть исключения, такие как glob bing без подстановочных знаков - как указал @ShadowRanger), поэтому я ' м не буду на них настаивать. Не говоря уже о том, что в некоторых случаях может потребоваться обработка имени файла.[Python 3]: os. доступ (< em> path, mode, *, dir_fd = None, effective_ids = False, follow_symlinks = True), поведение которого близко к
os.path.exists
(на самом деле оно шире, в основном из-за 2 nd sup> аргумент)- user permissions might restrict the file "visibility" as the doc states:
... проверить, есть ли у вызывающего пользователя указанный доступ к пути. mode должен быть F_OK для тестирования наличие пути ...
os.access("/tmp", os.F_OK)
Поскольку я также работаю на C, я также использую этот метод, потому что внутри он вызывает собственные API (опять же, через "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c"), но он также открывает ворота для возможных ошибок пользователя, а не как Python ic как и другие варианты. Итак, как правильно заметил @AaronHall, не используйте его, если вы не знаете, что делаете:
- Nix: [man7]: ДОСТУП (2) (!!! обратите внимание на примечание о дыре в безопасности, которую может вызвать его использование !!!)
- Win: [MS .Docs]: функция GetFileAttributesW
Примечание: вызов собственных API также возможен через [Python 3]: ctypes - библиотека сторонних функций для Python, но в большинстве случаев она более сложная.
(Win): поскольку vcruntime * (msvcr *) .dll экспортирует a [MS.Docs ]: _access, _waccess, а также семейство функций, вот пример:
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
Примечания:
- Хотя это не очень хорошая практика, я использую
os.F_OK
в вызове, но это просто для ясности (его значение - 0). - Я использую _waccess, чтобы один и тот же код работал на Python3 и Python2 (несмотря на различия, связанные с unicode между ними)
- Хотя это нацелено на очень конкретную область, об этом не упоминалось ни в одном из предыдущих ответов
Аналог Lnx (Ubtu (16 x64)), а также: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
Примечания:
Вместо этого жестко запрограммированный путь libc ("/lib/x86_64-linux-gnu/libc.so.6"), который может (и, скорее всего, будет) различаться в разных системах , None (или пустую строку) можно передать в конструктор CDLL (
ctypes.CDLL(None).access(b"/tmp", os.F_OK)
). Согласно [man7]: DLOPEN (3):Если filename имеет значение NULL, то возвращаемый дескриптор предназначен для основной программы. При передаче dlsym () этот дескриптор вызывает поиск символа в основной программе, за которым следуют все общие объекты, загружаемые при запуске программы, а затем все общие объекты, загружаемые с помощью dlopen strong> () с флагом RTLD_GLOBAL.
- Main (current) program (python) is linked against libc, so its symbols (including access) will be loaded
- С этим нужно обращаться осторожно, поскольку доступны такие функции, как main, Py_Main и (все) другие; вызов их может иметь катастрофические последствия (для текущей программы)
- Это также не относится к Win (но это не такая уж большая проблема, поскольку msvcrt.dll находится в "% SystemRoot% \ System32" em>, который по умолчанию находится в % PATH%). Я хотел пойти дальше и воспроизвести это поведение на Win (и отправить исправление), но, как оказалось, [MS.Docs]: функция GetProcAddress" видит "только экспортированные символы, поэтому, если кто-то объявляет функции в основном исполняемом файле как
__declspec(dllexport)
(почему, черт возьми, это делает обычный человек?), основная программа загружается, но в значительной степени непригодна для использования
- user permissions might restrict the file "visibility" as the doc states:
Установите сторонний модуль с возможностями файловой системы
Скорее всего, будет полагаться на один из способов, описанных выше (возможно, с небольшими настройками).
Одним из примеров может быть (опять же, для Win) [GitHub]: mhammond / pywin32 - Python для Windows (pywin32) Extensions, который является оболочкой Python над WINAPI.Но, поскольку это больше похоже на обходной путь, я останавливаюсь на этом.
Другой (неудачный) обходной путь (gainarie) - это (как я люблю его называть) подход sysadmin: используйте Python в качестве оболочки для выполнения команды оболочки
Победа:
(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
Итог:
- Используйте try / except / else em> / finally, потому что они могут предотвратить ряд неприятных проблем. Противоположным примером, который я могу придумать, является производительность: такие блоки являются дорогостоящими, поэтому старайтесь не помещать их в код, который должен запускаться сотни тысяч раз в секунду (но поскольку (в большинстве случаев) это связано с доступом к диску, это не так).
Заключительные примечания:
- Я постараюсь поддерживать его в актуальном состоянии, любые предложения приветствуются, я включу все полезное, что появится в ответе
glob.iglob
(а также glob.glob
) основаны на os.scandir
, так что теперь лениво; чтобы получить первое попадание в каталог из 10 миллионов файлов, вы сканируете только до первого попадания. И даже до версии 3.6, если вы используете glob
методы без каких-либо подстановочных знаков, функция умная: она знает, что у вас может быть только одно обращение, поэтому упрощает подстановку до os.path.isdir
или os.path.lexists
(в зависимости от того, заканчивается ли путь на /
).
- person ShadowRanger; 29.11.2017
os.path.isdir
или os.path.lexist
, поскольку это куча вызовов функций уровня Python и строковые операции до того, как он решит, что эффективный путь жизнеспособен, но без дополнительных системных вызовов или операций ввода-вывода, которые на порядки медленнее).
- person ShadowRanger; 29.11.2017
Python 3.4+ имеет объектно-ориентированный модуль пути: pathlib. Используя этот новый модуль, вы можете проверить, существует ли такой файл:
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
при открытии файлов:
try:
with p.open() as f:
# do awesome stuff
except OSError:
print('Well darn.')
В модуле pathlib есть много интересных вещей: удобная подстановка подстановки, проверка владельца файла, более легкое объединение путей и т. Д. Это стоит проверить. Если вы используете более старый Python (версия 2.6 или новее), вы все равно можете установить pathlib с помощью pip:
# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2
Затем импортируйте его следующим образом:
# Older Python versions
import pathlib2 as pathlib
pathlib.Path.exists
, который охватывает больше случаев, чем is_file
- person Ryan Haining; 12.10.2020
Это самый простой способ проверить, существует ли файл. Тот факт, что файл существовал, когда вы установили флажок, не гарантирует, что он будет там, когда вам нужно будет его открыть.
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")
Предпочитайте заявление о попытке. Это считается лучшим стилем и позволяет избежать условий гонки.
Не верьте мне на слово. Эта теория имеет множество подтверждений. Вот парочка:
- Стиль: Раздел «Обработка необычных условий» страницы http://allendowney.com/sd/notes/notes11.txt
- Как избежать гонок
try...except
не помогает решить эту проблему.
- person jstine; 28.09.2015
except:
приведет к тому, что исключение, возникающее в этой части вашего кода, вызовет сбивающее с толку сообщение (возникла вторая ошибка во время обработки первого.)
- person Camion; 24.05.2019
Как проверить, существует ли файл, с помощью Python без использования оператора try?
Теперь, доступный начиная с Python 3.4, импортируйте и создайте экземпляр объекта Path
с именем файла и проверьте метод is_file
(обратите внимание, что он также возвращает True для символических ссылок, указывающих на обычные файлы):
>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False
Если вы используете Python 2, вы можете выполнить обратный перенос модуля pathlib из pypi, pathlib2
или в противном случае проверьте isfile
из модуля os.path
:
>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False
Вышеупомянутое, вероятно, лучший прагматичный прямой ответ здесь, но есть вероятность состояния гонки (в зависимости от того, что вы пытаетесь выполнить), и тот факт, что базовая реализация использует try
, но Python использует try
везде в своем реализация.
Поскольку Python повсюду использует try
, на самом деле нет причин избегать реализации, которая его использует.
Но остальная часть этого ответа пытается учесть эти предостережения.
Более длинный и педантичный ответ
Доступен начиная с Python 3.4, используйте новый объект Path
в pathlib
. Обратите внимание на то, что .exists
не совсем верно, потому что каталоги не являются файлами (за исключением того, что в unix смысле все является файлом).
>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True
Итак, нам нужно использовать is_file
:
>>> root.is_file()
False
Вот справка по is_file
:
is_file(self)
Whether this path is a regular file (also True for symlinks pointing
to regular files).
Итак, давайте получим файл, который, как мы знаем, является файлом:
>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True
По умолчанию NamedTemporaryFile
удаляет файл при закрытии (и автоматически закрывается, когда на него больше не существует ссылок).
>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False
Если вы углубитесь в реализацию, вы увидим, что is_file
использует 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
Условия гонки: почему нам нравится пробовать
Нам нравится try
, потому что он позволяет избежать условий гонки. С try
вы просто пытаетесь прочитать свой файл, ожидая, что он там есть, а если нет, вы перехватываете исключение и выполняете любое резервное поведение, которое имеет смысл.
Если вы хотите проверить, существует ли файл, прежде чем пытаться его прочитать, и, возможно, вы удаляете его, а затем используете несколько потоков или процессов, или другая программа знает об этом файле и может его удалить - вы рискуете состояние гонки, если вы проверяете, что оно существует, потому что вы затем участвуете в гонке, чтобы открыть его до того, как его состояние (его существование) изменится.
Условия гонки очень сложно отлаживать, потому что есть очень маленькое окно, в котором они могут привести к сбою вашей программы.
Но если это ваша мотивация, вы можете получить значение оператора try
с помощью suppress
диспетчера контекста.
Избежание условий гонки без оператора try: suppress
Python 3.4 предоставляет нам suppress
контекстный менеджер (ранее _ 31_ диспетчер контекста), который семантически делает то же самое в меньшем количестве строк, а также (по крайней мере, внешне) соответствует исходный запрос, чтобы избежать заявления try
:
from contextlib import suppress
from pathlib import Path
Использование:
>>> with suppress(OSError), Path('doesnotexist').open() as f:
... for line in f:
... print(line)
...
>>>
>>> with suppress(OSError):
... Path('doesnotexist').unlink()
...
>>>
Для более ранних версий Pythons можно было использовать собственный suppress
, но без try
будет более подробным, чем с. Я верю, что это на самом деле единственный ответ, который не использует try
ни на каком уровне в Python, который может быть применен к более ранним версиям Python 3.4, потому что вместо этого он использует диспетчер контекста:
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)
Возможно, проще попробовать:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
Другие варианты, которые не соответствуют запросу «без попытки»:
isfile
import os
os.path.isfile(path)
из документов:
os.path.isfile(path)
Верните True, если путь - существующий обычный файл. Это следует за символическими ссылками, поэтому и
islink()
, иisfile()
могут быть истинными для одного и того же пути.
Но если вы изучите источник этой функции, вы Увидим, что он действительно использует оператор try:
# 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
Все, что он делает, это использует заданный путь, чтобы увидеть, может ли он получить статистику по нему, перехватывает OSError
и затем проверяет, является ли это файлом, если он не вызывает исключение.
Если вы собираетесь что-то сделать с файлом, я бы посоветовал напрямую попробовать это с помощью try, за исключением того, чтобы избежать состояния гонки:
try:
with open(path) as f:
f.read()
except OSError:
pass
os.access
Для Unix и Windows доступно os.access
, но для использования вы должны передавать флаги, и он не делает различий между файлами и каталогами. Это больше используется для проверки, имеет ли реальный вызывающий пользователь доступ в среде с повышенными привилегиями:
import os
os.access(path, os.F_OK)
Он также страдает теми же проблемами состояния гонки, что и isfile
. Из документов:
Примечание. Используя access (), чтобы проверить, авторизован ли пользователь, например, открытие файла до того, как это сделать, с помощью open () создает брешь в безопасности, потому что пользователь может использовать короткий промежуток времени между проверкой и открытием файла, чтобы манипулировать им. Предпочтительно использовать методы EAFP. Например:
if os.access("myfile", os.R_OK): with open("myfile") as fp: return fp.read() return "some default data"
лучше записать как:
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()
Избегайте использования os.access
. Это функция низкого уровня, которая имеет больше возможностей для ошибки пользователя, чем объекты и функции более высокого уровня, описанные выше.
Критика другого ответа:
Другой ответ говорит об этом о os.access
:
Лично я предпочитаю этот, потому что под капотом он вызывает собственные API (через "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c"), но он также открывает ворота для возможных ошибок пользователя, и он не такой Pythonic, как другие варианты. :
В этом ответе говорится, что он предпочитает не-питонический, подверженный ошибкам метод без каких-либо оснований. Кажется, это побуждает пользователей использовать низкоуровневые API, не понимая их.
Он также создает диспетчер контекста, который, безоговорочно возвращая True
, позволяет всем исключениям (включая KeyboardInterrupt
и SystemExit
!) Проходить без уведомления, что является хорошим способом скрыть ошибки.
Похоже, это побуждает пользователей применять неэффективные методы.
Проверка файлов и папок с os.path.isfile()
, os.path.isdir()
и os.path.exists()
Предполагая, что «путь» является допустимым путем, в этой таблице показано, что возвращает каждая функция для файлов и папок:
Вы также можете проверить, является ли файл определенным типом файла, используя os.path.splitext()
для получения расширения (если вы его еще не знаете).
>>> 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
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!"
Импорт os
упрощает навигацию и выполнение стандартных действий с вашей операционной системой.
Для справки также см. Как проверить, существует ли файл с помощью Python?
Если вам нужны высокоуровневые операции, используйте shutil
.
os.path.exists
возвращает истину для вещей, которые не являются файлами, например каталогов. Это дает ложные срабатывания. См. Другие ответы, рекомендующие os.path.isfile
.
- person Chris Johnson; 01.08.2015
В 2016 году лучшим способом по-прежнему остается использование os.path.isfile
:
>>> os.path.isfile('/path/to/some/file.txt')
Или в Python 3 вы можете использовать pathlib
:
import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
...
pathlib
- это ООП-решение Python для путей. Вы можете сделать с ним гораздо больше. Если вам просто нужно проверить наличие, преимущество не так велико.
- person KaiBuxe; 25.02.2016
Не похоже, что есть значимая функциональная разница между try / except и isfile()
, поэтому вам следует использовать тот, который имеет смысл.
Если вы хотите прочитать файл, если он существует, выполните
try:
f = open(filepath)
except IOError:
print 'Oh dear.'
Но если вы просто хотите переименовать файл, если он существует, и, следовательно, вам не нужно его открывать, выполните
if os.path.isfile(filepath):
os.rename(filepath, filepath + '.old')
Если вы хотите записать в файл, если он не существует, выполните
# 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'
Другое дело, если вам нужна блокировка файлов.
os.path.exists
возвращает истину для вещей, которые не являются файлами, например каталогов. Это дает ложные срабатывания. См. Другие ответы, рекомендующие os.path.isfile
.
- person Chris Johnson; 01.08.2015
filepath
с правильным временем, и BAM, вы перезаписываете целевой файл. Вы должны сделать open(filepath, 'wx')
в блоке try...except
, чтобы избежать проблемы.
- person spectras; 24.08.2015
OSError
, если filepath + '.old'
уже существует: в Windows, если dst уже существует, OSError будет вызвана, даже если это файл; может не быть способа реализовать атомарное переименование, когда dst дает имя существующему файлу.
- person Tom Myddeltyn; 24.05.2016
os.replace
переносимо работает без звука замена файла назначения (он идентичен поведению os.rename
в Linux) (ошибка возникает только в том случае, если имя назначения существует и является каталогом). Итак, вы застряли на 2.x, но у пользователей Py3 уже несколько лет есть хороший вариант.
- person ShadowRanger; 29.11.2017
rename
: это все равно нужно делать с _2 _ / _ 3_. os.rename
(или os.replace
в современном Python) является атомарным; установка проверки и переименования приводит к ненужной гонке и дополнительным системным вызовам. Просто сделай try: os.replace(filepath, filepath + '.old') except OSError: pass
- person ShadowRanger; 29.11.2017
Вы можете попробовать это (безопаснее):
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))
Выход будет:
([Errno 2] Нет такого файла или каталога: 'any.txt')
Затем, в зависимости от результата, ваша программа может просто продолжать работать оттуда или вы можете закодировать, чтобы остановить ее, если хотите.
try
- person rrs; 23.04.2014
Дата: 2017-12-04
Все возможные решения перечислены в других ответах.
Интуитивно понятный и аргументированный способ проверить, существует ли файл, заключается в следующем:
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')
Я сделал для вас исчерпывающую шпаргалку:
#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']}
Хотя я всегда рекомендую использовать операторы try
и except
, вот несколько возможностей для вас (мой личный фаворит - использование os.access
):
Попробуйте открыть файл:
Открытие файла всегда проверяет его существование. Вы можете сделать такую функцию:
def File_Existence(filepath): f = open(filepath) return True
Если задано значение False, выполнение остановится с необработанной ошибкой IOError или OSError в более поздних версиях Python. Чтобы поймать исключение, вы должны использовать предложение try except. Конечно, вы всегда можете использовать такой оператор
try
except` (спасибо hsandt за то, что заставили меня задуматься):def File_Existence(filepath): try: f = open(filepath) except IOError, OSError: # Note OSError is for later versions of Python return False return True
Используйте
os.path.exists(path)
:Это проверит наличие того, что вы указали. Однако он проверяет файлы и в каталогах, поэтому будьте осторожны с тем, как вы его используете.
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
Используйте
os.access(path, mode)
:Это проверит, есть ли у вас доступ к файлу. Он проверит разрешения. На основе документации os.py, набрав
os.F_OK
, он проверит существование пути. Однако использование этого создаст брешь в безопасности, поскольку кто-то может атаковать ваш файл, используя время между проверкой разрешений и открытием файла. Вместо этого вам следует перейти непосредственно к открытию файла, а не проверять его разрешения. (EAFP против LBYP). Если вы не собираетесь открывать файл после этого, а только проверяете его существование, вы можете использовать это.Во всяком случае, здесь:
>>> import os >>> os.access("/is/a/file.txt", os.F_OK) True
Я также должен упомянуть, что есть два способа, которыми вы не сможете проверить существование файла. Либо проблема будет permission denied
, либо no such file or directory
. Если вы поймаете IOError
, установите IOError as e
(как мой первый вариант), а затем введите print(e.args)
, чтобы вы могли, надеюсь, определить свою проблему. Я надеюсь, что это помогает! :)
Дополнительно os.access()
:
if os.access("myfile", os.R_OK):
with open("myfile") as fp:
return fp.read()
Являясь R_OK
, W_OK
и X_OK
флагами для проверки разрешений (doc а>).
Если файл предназначен для открытия, вы можете использовать один из следующих методов:
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!')
ОБНОВЛЕНИЕ
Чтобы избежать путаницы и на основании полученных ответов, текущий ответ находит либо файл , либо каталог с заданным именем.
os.path.exists
возвращает истину для вещей, которые не являются файлами, например каталогов. Это дает ложные срабатывания. См. Другие ответы, рекомендующие os.path.isfile
.
- person Chris Johnson; 01.08.2015
Самый простой способ сделать это - использовать
import os
if os.path.exists(FILE):
# file exists
pass
else:
# file does not exists
pass
из библиотеки ОС, а ФАЙЛ - относительный путь. В Windows это может или не работать, и вам, возможно, придется использовать путь освобождения, выполнив os.path.exists(os.path.join(os.path.abspath('./'), FILE))
, где ФАЙЛ по-прежнему является относительным путем плюс имя файла.
if os.path.isfile(path_to_file):
try:
open(path_to_file)
pass
except IOError as e:
print "Unable to open file"
Создание исключений считается приемлемым и питоническим подходом для управления потоком в вашей программе. Рассмотрите возможность обработки отсутствующих файлов с помощью IOErrors. В этой ситуации будет вызвано исключение IOError, если файл существует, но у пользователя нет разрешений на чтение.
SRC: http://www.pfinn.net/python-check-if-file-exists.html
Если вы уже импортировали NumPy для других целей, тогда нет необходимости импортировать другие библиотеки, такие как pathlib
, os
, paths
и т. Д.
import numpy as np
np.DataSource().exists("path/to/your/file")
Это вернет истину или ложь в зависимости от его существования.
Вы можете использовать os.path.exists ():
import os
print(os.path.exists("file"))
Надеюсь, это поможет: D
TL; DR одной строкой кода --- Keep It Simple
Чтобы проверить наличие файла или папки, используйте модуль Путь.
from pathlib import Path
if Path("myfile.txt").exists(): # works for both file and folders
# do stuffs...
Модуль pathlib
был представлен в Python 3.4
, поэтому вам понадобится Python 3.4+, эта библиотека значительно упрощает вашу жизнь и удобна в использовании, вот дополнительная документация об этом (https://docs.python.org/3/library/pathlib.html).
Кстати, если вы собираетесь повторно использовать путь, то лучше назначить его переменной
так станет
from pathlib import Path
p = Path("loc/of/myfile.txt")
if p.exists(): # works for both file and folders
# do stuffs...
Вы можете написать предложение Брайана без try:
.
from contextlib import suppress
with suppress(IOError), open('filename'):
process()
suppress
является частью Python 3.4. В более старых версиях вы можете быстро написать собственное подавление:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
Убедитесь, что файл или каталог существует
Вы можете воспользоваться этими тремя способами:
Примечание 1.
os.path.isfile
используется только для файлов
import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists
Примечание 2:
os.path.exists
используется как для файлов, так и для каталогов.
import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists
Метод
pathlib.Path
(включен в Python 3+, устанавливается с помощью pip для Python 2)
from pathlib import Path
Path(filename).exists()
Добавление еще одного небольшого изменения, которое не совсем отражено в других ответах.
Это будет обрабатывать случай, когда file_path
является None
или пустой строкой.
def file_exists(file_path):
if not file_path:
return False
elif not os.path.isfile(file_path):
return False
else:
return True
Adding a variant based on suggestion from Shahbaz
def file_exists(file_path):
if not file_path:
return False
else:
return os.path.isfile(file_path)
Добавление варианта на основе предложения Питера Вуда
def file_exists(file_path):
return file_path and os.path.isfile(file_path):
if (x) return true; else return false;
на самом деле просто return x
. Ваши последние четыре строки могут стать return os.path.isfile(file_path)
. Пока мы это делаем, всю функцию можно упростить как return file_path and os.path.isfile(file_path)
.
- person Shahbaz; 05.01.2017
return x
в случае if (x)
. Python будет считать пустую строку False, и в этом случае мы вернем пустую строку вместо bool. Цель этой функции - всегда возвращать bool.
- person Marcel Wilson; 05.01.2017
x
равно os.path.isfile(..)
, так что это уже bool.
- person Shahbaz; 05.01.2017
os.path.isfile(None)
вызывает исключение, поэтому я добавил проверку if. Я, вероятно, мог бы просто обернуть это в try / except, но я чувствовал, что так это более явно.
- person Marcel Wilson; 05.01.2017
Я являюсь автором пакета, который существует уже около 10 лет, и в нем есть функция, которая напрямую решает этот вопрос. Обычно, если вы работаете в системе, отличной от Windows, она использует Popen
для доступа к find
. Однако, если вы работаете в Windows, он реплицирует find
с помощью эффективного обходчика файловой системы.
Сам код не использует try
блок ... кроме определения операционной системы и, таким образом, направляет вас к "Unix" -стилю find
или ручному построению find
. Временные тесты показали, что try
быстрее определял ОС, поэтому я использовал ее там (но больше нигде).
>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']
И документ…
>>> 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']
>>>
Реализация, если хотите, находится здесь: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190
Вот однострочная команда Python для среды командной строки Linux. Я нахожу это ОЧЕНЬ УДОБНЫМ, так как я не такой уж горячий парень с Bash.
python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"
Надеюсь, это будет полезно.
[ -f "${file}" ] && echo "file found" || echo "file not found"
(то же самое, что и if [ ... ]; then ...; else ...; fi
).
- person flotzilla; 01.10.2015
Вы можете использовать библиотеку "OS" Python:
>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt")
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False
os.path.exists
возвращает истину для вещей, которые не являются файлами, например каталогов. Это дает ложные срабатывания. См. Другие ответы, рекомендующие os.path.isfile
.
- person Chris Johnson; 01.08.2015
exists
в порядке. Если цель состоит в том, чтобы определить, безопасно ли открывать предположительно существующий файл, то критика оправдана и существует недостаточно точно. К сожалению, OP не указывает, какая цель является желаемой (и, вероятно, больше этого не будет).
- person starturtle; 05.09.2017
Как проверить, существует ли файл, без использования оператора try?
В 2016 году это, пожалуй, самый простой способ проверить, существует ли файл и является ли он файлом:
import os
os.path.isfile('./file.txt') # Returns True if exists, else False
isfile
на самом деле просто вспомогательный метод, который внутри использует os.stat
и stat.S_ISREG(mode)
внизу. Этот os.stat
метод нижнего уровня, который предоставит вам подробную информацию о файлах, каталогах, сокетах, буферах и многом другом. Подробнее о os.stat здесь
Примечание. Однако этот подход никоим образом не заблокирует файл, и поэтому ваш код может стать уязвимым для «времени проверки до времени использования» (TOCTTOU ) ошибки.
Таким образом, создание исключений считается приемлемым и питоническим подходом для управления потоком в вашей программе. И следует рассмотреть возможность обработки отсутствующих файлов с помощью IOErrors, а не if
операторов (просто совет).
Вы можете использовать следующий открытый метод, чтобы проверить, существует ли файл + доступен для чтения:
file = open(inputFile, 'r')
file.close()
Вам обязательно стоит использовать этот.
from os.path import exists
if exists("file") == True:
print "File exists."
elif exists("file") == False:
print "File doesn't exist."
exists
. Если файл создается после if
, но до elif
, ни одна ветвь не выполняется. Было бы лучше просто изменить это на else
, чтобы, по крайней мере, сделать код детерминированным.
- person tripleee; 22.08.2013
os.path.exists
возвращает истину для вещей, которые не являются файлами, например каталогов. Это дает ложные срабатывания. См. Другие ответы, рекомендующие os.path.isfile
.
- person Chris Johnson; 03.08.2015
import os
path = /path/to/dir
root,dirs,files = os.walk(path).next()
if myfile in files:
print "yes it exists"
Это полезно при проверке нескольких файлов. Или вы хотите выполнить пересечение / вычитание набора с существующим списком.
os.walk
найти все файлы в дереве каталогов - если пользователь хочет проверить ./FILE
, маловероятно, что он захочет рассматривать ./some/sub/folder/FILE
как совпадение, что и делает ваше решение; и (2) ваше решение очень неэффективно по сравнению с простым вызовом os.path.isfile()
в случае, когда есть много файлов ниже текущего каталога. В случае, если в дереве не существует подходящего имени файла без пути, ваш код перечислит каждый файл в дереве перед возвратом false.
- person Chris Johnson; 14.06.2017
Чтобы проверить, существует ли файл,
from sys import argv
from os.path import exists
script, filename = argv
target = open(filename)
print "file exists: %r" % exists(filename)
Методы exists () и is_file () объекта Path могут использоваться для проверки того, существует ли заданный путь и является ли он файлом.
Программа Python 3 для проверки существования файла:
# File name: check-if-file-exists.py
from pathlib import Path
filePath = Path(input("Enter path of the file to be found: "))
if filePath.exists() and filePath.is_file():
print("Success: File exists")
else:
print("Error: File does not exist")
Вывод:
$ python3 check-if-file-exists.py
Введите путь к файлу, который нужно найти: /Users/macuser1/stack-overflow/index.html
Успех: Файл существует
$ python3 check-if-file-exists.py
Введите путь к файлу, который нужно найти: hghjg jghj
Ошибка: Файл не существует
Вы можете использовать os.listdir, чтобы проверить, находится ли файл в определенном каталоге.
import os
if 'file.ext' in os.listdir('dirpath'):
#code
import os
# for testing purpose args defaulted to current folder & file.
# returns True if file found
def file_exists(FOLDER_PATH='../', FILE_NAME=__file__):
return os.path.isdir(FOLDER_PATH) \
and os.path.isfile(os.path.join(FOLDER_PATH, FILE_NAME))
Обычно это проверка папки, а затем проверка файла с правильным разделителем каталогов с помощью os.path.join.
Используйте os.path.exists (), чтобы проверить, существует ли файл. или не:
def fileAtLocation(filename,path):
return os.path.exists(path + filename)
filename="dummy.txt"
path = "/home/ie/SachinSaga/scripts/subscription_unit_reader_file/"
if fileAtLocation(filename,path):
print('file found at location..')
else:
print('file not found at location..')
isfile()
, exists()
вернет True для каталогов.
- person Pranav Hosangadi; 30.09.2020
Другой возможный вариант - проверить, находится ли имя файла в каталоге с помощью os.listdir ()
import os
if 'foo.txt' in os.listdir():
# Do things
это вернет истину, если это так, и ложь, если нет
Используйте следующий код:
def findfile(filepath):
flag = False
for filename in os.listdir(filepath)
if filename == "your file name":
flag = True
break
else:
print("no file found")
if flag == True:
return True
else:
return False
flag
. Кроме того, true
и false
должны быть написаны с заглавной буквы. См. Встроенные константы.
- person Georgy; 11.12.2020
isReadableFile(path,fileName)
вернет True
, если файл доступен и доступен для чтения процессу \ программе \ потоку
- person Khaled.K; 09.08.2015
my_path.exists()
. - person Charlie Parker   schedule 06.08.2020