Как узнать, существует ли файл или нет, без использования инструкции try
?
Как проверить, существует ли файл без исключений?
Ответ 1
Если причина, по которой вы проверяете, заключается в том, что вы можете сделать что-то вроде if file_exists: open_it()
, безопаснее использовать try
при попытке открыть его. Проверка и последующее открытие может привести к удалению или перемещению файла, а также к тому, что вы проверяете и когда пытаетесь открыть его.
Если вы не планируете открывать файл немедленно, вы можете использовать os.path.isfile
Верните
True
если путь - это существующий обычный файл. Это следует за символическими ссылками, поэтому и islink(), и isfile() могут быть истинными для одного и того же пути.
import os.path
os.path.isfile(fname)
если вам нужно убедиться, что это файл.
Начиная с Python 3.4, модуль pathlib
предлагает объектно-ориентированный подход (pathlib2
в 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
Ответ 2
У вас есть функция os.path.exists
:
import os.path
os.path.exists(file_path)
Это возвращает True
как для файлов, так и для каталогов, но вместо этого вы можете использовать
os.path.isfile(file_path)
для проверки, если это файл. Это следует за символическими ссылками.
Ответ 3
В отличие от isfile()
, exists()
будет return True
для каталогов.
Поэтому в зависимости от того, хотите ли вы использовать только обычные файлы или каталоги, вы будете использовать isfile()
или exists()
. Вот простой вывод REPL.
>>> 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
Ответ 4
import os.path
if os.path.isfile(filepath):
Ответ 5
Используйте os.path.isfile()
с os.access()
:
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"
Ответ 6
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
Ответ 7
Хотя почти все возможные способы были перечислены в (по крайней мере, одном из) существующих ответов (например, добавлен материал, специфичный для Python 3.4), я постараюсь сгруппировать все вместе.
Примечание: каждый фрагмент кода стандартной библиотеки Python, который я собираюсь опубликовать, относится к версии 3.5.3.
Постановка проблемы:
- Проверить наличие файла (спорный: также папка ("специальный" файл)?)
- Не используйте блоки try/исключением/else/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/исключением вокруг [Python 3]: os. stat (путь, *, dir_fd = нет, follow_symlinks = True). Итак, ваш код попробуйте/за исключением бесплатного, но ниже в стеке фреймов (как минимум) один такой блок. Это также относится к другим функциям (включая
os.path.isfile
).1.1. [Python 3]: путь. is_file()
- Это более изящный (и более питонический) способ обработки путей, но
-
Под капотом, он делает то же самое (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
поведение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/исключением/else/finally, как [Python 3]: Оператор with гласит:Это позволяет инкапсулировать обычные попытки... кроме... наконец, шаблонов использования для удобного повторного использования.
-
-
Функции обхода файловой системы (и поиск результатов по соответствующим элементам)
-
[Python 3]: ос. listdir (путь = ' ') (или [Python 3]:. ОС ScanDir (путь =)'.' на Python v 3.5 +, 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]: ос. ходьба (top, topdown = True, onerror = None, последующие ссылки = False)
- Он использует
os.listdir
(os.scandir
когда доступно)
- Он использует
- [Питон 3]: шар. iglob (pathname, *, recursive = False) (или его предшественник:
glob.glob
)- Сама по себе функция обхода не выглядит (по крайней мере, в некоторых случаях), но она по-прежнему использует
os.listdir
- Сама по себе функция обхода не выглядит (по крайней мере, в некоторых случаях), но она по-прежнему использует
Так как они перебирают папки, (в большинстве случаев) они неэффективны для нашей проблемы (есть исключения, такие как глобализация без подстановочных знаков - как указывал @ShadowRanger), поэтому я не буду настаивать на них. Не говоря уже о том, что в некоторых случаях может потребоваться обработка имени файла. -
-
[Python 3]: ос. доступа (путь, режим, *, dir_fd = нет, effective_ids = false, follow_symlinks = TRUE), поведение которого близка к
os.path.exists
( на самом деле это шире, в основном из-за 2 - й аргумент)- пользовательские разрешения могут ограничивать "видимость" файла, как указано в документе:
... проверить, имеет ли вызывающий пользователь указанный доступ к пути. режим должен быть F_OK, чтобы проверить существование пути...
os.access("/tmp", os.F_OK)
Так как я также работаю в C, я также использую этот метод, потому что внутри него он вызывает собственные API (опять же, через "$ {PYTHON_SRC_DIR}/Modules/posixmodule.c"), но он также открывает ворота для возможных ошибок пользователя., и это не так Pythonic, как другие варианты. Итак, как правильно заметил @AaronHall, не используйте его, если не знаете, что делаете:
- Nix: [man7]: ACCESS (2) (!!! обратите внимание на примечание о дыре в безопасности, которую может привести к его использованию !!!)
- Win: [MS.Docs]: функция GetFileAttributesW
Примечание: вызов нативных API также возможен через [Python 3]: ctypes - библиотека сторонних функций для Python, но в большинстве случаев она более сложная.
(Зависит от Win): поскольку vcruntime * (msvcr *).dll экспортирует также [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 (несмотря на различия между ними, связанные с юникодом)
- Хотя это касается очень конкретной области, она не упоминалась ни в одном из предыдущих ответов.
Аналог 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 (или пустая строка) можно передать конструктору
ctypes.CDLL(None).access(b"/tmp", os.F_OK)
(ctypes.CDLL(None).access(b"/tmp", os.F_OK)
). Согласно [man7]: DLOPEN (3):Если имя файла NULL, то возвращаемый дескриптор для основной программы. Когда задано dlsym(), этот дескриптор вызывает поиск символа в основной программе, за которым следуют все общие объекты, загружаемые при запуске программы, а затем все общие объекты, загружаемые dlopen() с флагом RTLD_GLOBAL.
- Основная (текущая) программа (python) связана с libc, поэтому ее символы (включая доступ) будут загружены
- С этим нужно обращаться осторожно, поскольку доступны такие функции, как main, Py_Main и (все остальные); их вызов может иметь катастрофические последствия (для текущей программы)
- Это также не относится к Win (но это не такая уж большая проблема, поскольку msvcrt.dll находится в "% SystemRoot%\System32", который по умолчанию находится в% PATH%). Я хотел пойти дальше и повторить это поведение в Win (и отправить патч), но, как оказалось, [MS.Docs]: функция GetProcAddress "видит" только экспортированные символы, поэтому, если кто-то не объявит функции в основном исполняемом файле как
__declspec(dllexport)
(почему на Земле обычный человек будет делать это?), основная программа загружаема, но в значительной степени непригодна для использования
- пользовательские разрешения могут ограничивать "видимость" файла, как указано в документе:
-
Установите какой-нибудь сторонний модуль с возможностями файловой системы
Скорее всего, будет опираться на один из способов выше (возможно, с небольшими настройками).
Одним примером может быть (опять же, специфичный для Win) [GitHub]: mhammond/pywin32 - расширения Python для Windows (pywin32), которые являются оболочкой 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
-
Никс (Lnx (Убту)):
[[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp\" > /dev/null 2>&1'))" 0 [[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp.notexist\" > /dev/null 2>&1'))" 512
-
Итог:
- Используют ли попробовать/за исключением/иначе/наконец блоков, потому что они могут помешать вам запуск в серию неприятных проблем. Контр-пример, о котором я могу подумать, - это производительность: такие блоки являются дорогостоящими, поэтому постарайтесь не помещать их в код, который он должен запускать сотни тысяч раз в секунду (но поскольку (в большинстве случаев) он предполагает доступ к диску, это не будет так).
Финальная заметка (и):
- Я постараюсь держать это в курсе, любые предложения приветствуются, я включу что-нибудь полезное, что придет в ответ
Ответ 8
Это самый простой способ проверить, существует ли файл. Просто , потому что файл существовал, когда вы отметили, не гарантирует, что он будет там, когда вам нужно его открыть.
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")
Ответ 9
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
Ответ 10
Предпочитаете оператор try. Он считается лучшим стилем и избегает условий гонки.
Не верьте мне на слово. Там много поддержки этой теории. Вот пара:
- Стиль: раздел "Обработка необычных условий" http://allendowney.com/sd/notes/notes11.txt
- Избежать условий гонки
Ответ 11
Как проверить, существует ли файл, используя 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
Здесь help на 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
вы просто пытаетесь прочитать свой файл, ожидая, что он будет там, а если нет, вы поймаете исключение и выполните все возможные действия резервного копирования.
Если вы хотите проверить, существует ли файл перед попыткой его прочитать, и вы можете удалить его, а затем вы можете использовать несколько потоков или процессов, или другая программа знает об этом файле и может удалить его - вы рискуете шанс гоночного состояния, если вы проверите его, потому что вы затем мчатесь, чтобы открыть его, прежде чем его состояние (его существование) изменится.
Условия гонки очень сложно отлаживать, потому что есть очень маленькое окно, в котором они могут привести к сбою вашей программы.
Но если это ваша мотивация, вы можете получить значение инструкции try
с помощью диспетчера контекстов suppress
.
Избегайте условий гонки без инструкции try: suppress
Python 3.4 дает нам suppress
контекстный менеджер (ранее ignore
контекстный менеджер), который делает семантически точно одно и то же в меньшем количестве строк, а также (по крайней мере поверхностно), удовлетворяя первоначальному запросу, чтобы избежать инструкции 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)
из docs:
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-except, чтобы избежать условия гонки:
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
. Из docs:
Примечание: Использование 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
!)), что является хорошим способом скрыть ошибки.
Это, по-видимому, побуждает пользователей принимать плохие практики.
Ответ 12
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
.
Ответ 13
Тестирование файлов и папок с помощью 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
Ответ 14
В 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():
...
Ответ 15
Кажется, что нет смысла в функциональной разнице между 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'
Если вам нужна блокировка файлов, это другое дело.
Ответ 16
Вы можете попробовать это (безопаснее):
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] Нет такого файла или каталога: 'Whatever.txt')
Затем, в зависимости от результата, ваша программа может просто продолжать работать оттуда или вы можете закодировать ее, если хотите.
Ответ 17
Хотя я всегда рекомендую использовать инструкции 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 vs 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)
, чтобы вы могли, надеюсь, определить вашу проблему. Я надеюсь, что это помогает!:)
Ответ 18
Дата: 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']}
Ответ 19
Кроме того, os.access()
:
if os.access("myfile", os.R_OK):
with open("myfile") as fp:
return fp.read()
Быть R_OK
, W_OK
и X_OK
флаги для проверки разрешений (doc).
Ответ 20
В Python 3.4 язык предоставляет новый модуль для управления файлами:
import pathlib
path = pathlib.Path('path/to/file')
if path.is_file(): # If you want to check a directory: path.is_dir()
# If it is true, return true on your code.
Ответ 21
Если файл открыт, вы можете использовать один из следующих способов:
>>> 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!')
ОБНОВИТЬ
Чтобы избежать путаницы и на основании полученных ответов, текущий ответ находит либо файл, либо каталог с заданным именем.
Ответ 22
if os.path.isfile(path_to_file):
try:
open(path_to_file)
pass
except IOError as e:
print "Unable to open file"
Принятие исключений считается приемлемым, а Pythonic, подход к управлению потоком в вашей программе. Рассмотрите возможность обработки отсутствующих файлы с IOErrors. В этой ситуации исключение IOError будет если файл существует, но пользователь не имеет прав на чтение.
Ответ 23
Просто чтобы добавить к путанице, кажется, что предложенный ранее метод try: open() не работает в Python, поскольку доступ к файлам не является исключительным, даже при записи в файлы, c.f. Каков наилучший способ открыть файл для эксклюзивного доступа в Python?.
Ответ 24
Если вы импортировали NumPy уже для других целей, нет необходимости импортировать другие библиотеки, такие как pathlib
, os
, paths
и т.д.
import numpy as np
np.DataSource().exists("path/to/your/file")
Это вернет true или false, основываясь на его существовании.
Ответ 25
Вы можете написать предложение Брайана без 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
Ответ 26
Проверить файл или каталог
Вы можете выполнить следующие три способа:
Примечание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+, устанавливается с помощью пипа для Python 2)
from pathlib import Path
Path(filename).exists()
Ответ 27
Я являюсь автором пакета, который существует около 10 лет, и у него есть функция, которая напрямую решает этот вопрос. В принципе, если вы находитесь в системе, отличной от Windows, она использует Popen
для доступа к find
. Однако, если вы находитесь в Windows, он реплицирует find
эффективным ходоком файловой системы.
В самом коде не используется блок try
... кроме определения операционной системы и, таким образом, управление вами в стиле "Unix" find
или ручном built 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
Ответ 28
Добавление еще одной небольшой вариации, которая не совсем отражена в других ответах.
Это будет обрабатывать случай 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
Добавление варианта, основанного на предположении от Шахбаза
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):
Ответ 29
Здесь приведена 1 строка команды Python для среды командной строки Linux. Я нахожу это ОЧЕНЬ HANDY, так как я не такой горячий парень Bash.
python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"
Я надеюсь, что это будет полезно.
Ответ 30
Вы можете использовать библиотеку "OS" Python:
>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt")
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False