Ответы:
Если причина, по которой вы проверяете, заключается в том, что вы можете сделать что-то подобное if file_exists: open_it(), безопаснее использовать tryвокруг попытки открыть его. Проверка и последующее открытие может привести к удалению или перемещению файла, а также к тому, что вы проверяете и когда пытаетесь открыть его.
Если вы не планируете открыть файл сразу, вы можете использовать os.path.isfile
Вернуть,
Trueесли путь является существующим обычным файлом. Это следует за символическими ссылками, поэтому и islink (), и isfile () могут быть истинными для одного и того же пути.
import os.path
os.path.isfile(fname)
если вам нужно убедиться, что это файл.
Начиная с Python 3.4, pathlibмодуль предлагает объектно-ориентированный подход (перенесенный 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
open('file', 'r+')) и затем искать до конца.
У вас есть os.path.existsфункция:
import os.path
os.path.exists(file_path)
Это возвращает Trueкак файлы, так и каталоги, но вместо этого вы можете использовать
os.path.isfile(file_path)
проверить, если это файл специально. Это следует за символическими ссылками.
В отличие от isfile(), exists()вернется 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.
import os, вам не нужно import os.pathснова, так как он уже является частью os. Вам просто нужно импортировать, os.pathесли вы собираетесь использовать функции os.pathтолько из osсебя, а не из себя, чтобы импортировать меньшую вещь, но по мере использования os.accessи os.R_OK, второй импорт не нужен.
import os
os.path.exists(path) # Returns whether the path (directory or file) exists or not
os.path.isfile(path) # Returns whether the file exists or not
Хотя почти все возможные способы были перечислены в (по крайней мере, одном из) существующих ответов (например, добавлен материал, специфичный для Python 3.4 ), я постараюсь сгруппировать все вместе.
Примечание : каждый фрагмент кода стандартной библиотеки Python, который я собираюсь опубликовать, относится к версии 3.5.3 .
Постановка проблемы :
Возможные решения :
[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поведение (обратите внимание, что это только для демонстрационных целей, не пытайтесь писать такой код для производства ):
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. подавить ( * исключения ) - который был специально разработан для выборочного подавления исключений
Но, кажется, что они обертки за попытки / за исключением / еще / , наконец , блоки, так как [Python 3]: А с заявлением гласит:
Это позволяет инкапсулировать обычные попытки ... кроме ... наконец, шаблонов использования для удобного повторного использования.
Функции обхода файловой системы (и поиск результатов по соответствующим элементам)
[Python 3]: ос. listdir ( путь = '' ) (или [Python 3]:. ОС ScanDir ( '' = путь ) на Python против 3,5 + портировать: [PyPI]: ScanDir )
Под капотом оба используют:
через [GitHub]: python / cpython - (основной) cpython / Modules / posixmodule.c
Использование scandir () вместо listdir () может значительно повысить производительность кода, который также нуждается в информации о типе файла или атрибуте файла, поскольку объекты os.DirEntry предоставляют эту информацию, если операционная система предоставляет ее при сканировании каталога. Все методы os.DirEntry могут выполнять системный вызов, но для is_dir () и is_file () обычно требуется только системный вызов для символических ссылок; os.DirEntry.stat () всегда требует системного вызова в Unix, но требует только одного для символических ссылок в Windows.
os.listdir( os.scandirкогда доступно)glob.glob)
os.listdir
Так как эти итерации по папкам, (в большинстве случаев) они неэффективны для нашей задачи (есть исключения, например , не символов подстановки Глоб Бинг - в @ShadowRanger указывал), так что я не буду настаивать на них. Не говоря уже о том, что в некоторых случаях может потребоваться обработка имени файла.
[Python 3]: ос. доступа ( путь, режим, *, dir_fd = None, effective_ids = False, follow_symlinks = True ) , поведение которых близка к os.path.exists( на самом деле это шире, в основном из - за 2 - й аргумент)
... проверить, имеет ли вызывающий пользователь указанный доступ к пути . режим должен быть F_OK, чтобы проверить существование пути ...
os.access("/tmp", os.F_OK)
Так как я работаю в C , я использую этот метод, а потому , что под капотом, он вызывает нативный API s (опять же , с помощью «$ {} PYTHON_SRC_DIR /Modules/posixmodule.c» ), но он также открывает ворота для возможного пользователя ошибки , и это не так, как Python ic, как другие варианты. Итак, как правильно заметил @AaronHall, не используйте его, если не знаете, что делаете:
Примечание : вызов нативных 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 )
Lnx ( Ubtu (16 x 64) ) аналог , а также:
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) :
Если имя файла NULL, то возвращаемый дескриптор для основной программы. При передаче dlsym () этот дескриптор вызывает поиск символа в основной программе, за которым следуют все общие объекты, загруженные при запуске программы, а затем все общие объекты, загружаемые dlopen () с флагом RTLD_GLOBAL .
__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 ( Убту )):
[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
Итог :
Финальные заметки :
glob.iglob(и glob.globтакже) основаны наos.scandir , так что теперь лениво; чтобы получить первый удар в каталоге из 10M файлов, вы сканируете только до первого попадания. И даже до 3.6, если вы используете globметоды без каких-либо подстановочных знаков, функция умна: она знает, что вы можете сделать только один удар, поэтому она упрощает сглаживание до всего os.path.isdirилиos.path.lexists (в зависимости от того, заканчивается ли путь /).
os.path.isdirили os.path.lexistпоскольку это набор вызовов функций уровня Python и строки операции, прежде чем он решит, что эффективный путь является жизнеспособным, но не требуется никаких дополнительных системных вызовов или операций ввода-вывода, что на несколько порядков медленнее).
Это самый простой способ проверить, существует ли файл. Тот факт, что файл существовал при проверке, не гарантирует, что он будет там, когда вам нужно его открыть.
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+ есть объектно-ориентированный модуль пути: 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
Предпочитаю оператор try. Это считается лучшим стилем и избегает условий гонки.
Не верь мне на слово. Есть много поддержки этой теории. Вот пара:
try...exceptне помогает решить эту проблему в любом случае.
except:предложение приведет к тому, что исключение, возникающее в этой части вашего кода, вызовет сбивающее с толку сообщение (вторая ошибка возникает во время обработка первого.)
Как проверить, существует ли файл с использованием 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 менеджера контекста.
suppressPython 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()
...
>>>
Для более ранних Питонов, вы можете бросить свои собственные 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:
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!) Проходить без вывода сообщений, что является хорошим способом скрыть ошибки.
Это, кажется, поощряет пользователей принимать плохие методы.
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возвращает true для вещей, которые не являются файлами, например, для каталогов. Это дает ложные срабатывания. Смотрите другие ответы, которые рекомендуют os.path.isfile.
Тестирование файлов и папок с помощью 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
В 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 для путей. Вы можете сделать намного больше с этим. Если вам просто нужно проверить существование, преимущество не так велико.
Не похоже, что между try / кроме и есть существенная функциональная разница 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возвращает true для вещей, которые не являются файлами, например, для каталогов. Это дает ложные срабатывания. Смотрите другие ответы, которые рекомендуют os.path.isfile.
filepathс правильным временем, и BAM перезаписывает целевой файл. Вы должны сделать open(filepath, 'wx')в try...exceptблоке, чтобы избежать проблемы.
OSErrorесли filepath + '.old'уже существует: «В Windows, если dst уже существует, OSError будет вызываться, даже если это файл; может быть невозможно реализовать атомарное переименование, когда dst называет существующий файл. "
os.replace переносимо выполняет автоматическую замену файла назначения (он идентичен os.renameповедению Linux) (он только выдает ошибки, если имя назначения существует и является каталогом). Итак, вы застряли на 2.x, но у пользователей Py3 был хороший выбор уже несколько лет.
renameпримере: это все еще должно быть сделано с try/ except. os.rename(или os.replaceна современном Python) является атомарным; проверка его, а затем переименование приводит к ненужной гонке и дополнительным системным вызовам. Просто сделайtry: os.replace(filepath, filepath + '.old') except OSError: pass
Вы можете попробовать это (безопаснее):
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] Нет такого файла или каталога: 'what.txt')
Затем, в зависимости от результата, ваша программа может просто продолжать работать оттуда или вы можете написать код, чтобы остановить его, если хотите.
try
Хотя я всегда рекомендую использовать tryи exceptзаявления, вот несколько возможностей для вас (мой личный фаворит использует os.access):
Попробуйте открыть файл:
Открытие файла всегда проверяет его наличие. Вы можете сделать функцию так:
def File_Existence(filepath):
f = open(filepath)
return True
Если это значение False, оно прекратит выполнение с неуправляемым IOError или OSError в более поздних версиях Python. Чтобы поймать исключение, вы должны использовать предложение try, кроме. Конечно, вы всегда можете использовать tryвыражение "исключение" вот так (спасибо 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его, он проверит наличие пути. Однако использование этого создаст дыру в безопасности, поскольку кто-то может атаковать ваш файл, используя время между проверкой прав доступа и открытием файла. Вместо этого вам следует перейти непосредственно к открытию файла вместо проверки его прав доступа. ( ЭСПЦ против 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)чтобы вы могли надеяться определить вашу проблему. Я надеюсь, что это помогает! :)
Дата: 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']}
Если файл предназначен для открытия, вы можете использовать один из следующих методов:
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возвращает true для вещей, которые не являются файлами, например, для каталогов. Это дает ложные срабатывания. Смотрите другие ответы, которые рекомендуют os.path.isfile.
if os.path.isfile(path_to_file):
try:
open(path_to_file)
pass
except IOError as e:
print "Unable to open file"
Поднятие исключений считается приемлемым и питонским подходом для управления потоком в вашей программе. Подумайте об обработке отсутствующих файлов с ошибками ввода-вывода. В этой ситуации возникнет исключение IOError, если файл существует, но у пользователя нет прав на чтение.
Вы можете написать предложение Брайана без 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
Я являюсь автором пакета, который существует уже около 10 лет, и у него есть функция, которая решает этот вопрос напрямую. В основном, если вы работаете не в системе Windows, она использует Popenдля доступа find. Тем не менее, если вы находитесь в Windows, он копируетfind с эффективным обходчиком файловой системы.
Сам код не использует tryблок ... за исключением определения операционной системы и, следовательно, findперехода к стилю «Unix» или «hand-buillt» 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
Вы можете следовать этим трем путям:
Примечание 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()
Добавление еще одного небольшого изменения, которое не совсем отражено в других ответах.
Это будет обрабатывать случай 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):
if (x) return true; else return false;это действительно просто return x. Ваши последние четыре строки могут стать return os.path.isfile(file_path). Пока мы на этом, вся функция может быть упрощена как return file_path and os.path.isfile(file_path).
return xв случае if (x). Python будет рассматривать пустую строку False, в этом случае мы будем возвращать пустую строку вместо bool. Цель этой функции - всегда возвращать bool.
xэто os.path.isfile(..)так уже BOOL.
os.path.isfile(None)вызывает исключение, поэтому я добавил проверку if. Я мог бы, вероятно, просто обернуть это в попытку / за исключением, но я чувствовал, что это было более явно таким образом.
return file_path and os.path.isfile(file_path)
Вот 1-строчная команда Python для среды командной строки Linux. Я нахожу это ОЧЕНЬ ХЕНДИ, так как я не такой горячий парень из Баш
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).
Вы можете использовать библиотеку "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возвращает true для вещей, которые не являются файлами, например, для каталогов. Это дает ложные срабатывания. Смотрите другие ответы, которые рекомендуют os.path.isfile.
existsэто нормально. Если цель состоит в том, чтобы определить, безопасно ли открывать предположительно существующий файл, то критика оправдана и существует недостаточно точно. К сожалению, ОП не определяет, какая цель является желаемой (и, вероятно, больше не будет).
Как проверить, существует ли файл, без использования оператора 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 ).
Поэтому повышение исключений считается приемлемым и питонским подходом для управления потоком в вашей программе. И нужно рассмотреть обработку отсутствующих файлов с ошибками ввода-вывода, а неif заявлениями ( просто совет ).
import os.path
def isReadableFile(file_path, file_name):
full_path = file_path + "/" + file_name
try:
if not os.path.exists(file_path):
print "File path is invalid."
return False
elif not os.path.isfile(full_path):
print "File does not exist."
return False
elif not os.access(full_path, os.R_OK):
print "File cannot be read."
return False
else:
print "File can be read."
return True
except IOError as ex:
print "I/O error({0}): {1}".format(ex.errno, ex.strerror)
except Error as ex:
print "Error({0}): {1}".format(ex.errno, ex.strerror)
return False
#------------------------------------------------------
path = "/usr/khaled/documents/puzzles"
fileName = "puzzle_1.txt"
isReadableFile(path, fileName)
isReadableFile(path,fileName)вернется, Trueесли файл доступен и читается процессом \ program \ thread