Ответы:
Если причина, по которой вы проверяете, заключается в том, что вы можете сделать что-то подобное 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
менеджера контекста.
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()
...
>>>
Для более ранних Питонов, вы можете бросить свои собственные 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