Как проверить, существует ли файл без исключений?

Как мне проверить, существует файл или нет, без использования оператора try?

Чтобы проверить, существует ли объект Path независимо от того, является ли он файлом или каталогом, используйте my_path.exists().

Charlie Parker 06.08.2020 22:40
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
6 035
1
4 237 494
40

Ответы 40

import os.path

if os.path.isfile(filepath):
   print("File exists")

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

Как правило, не рекомендуется называть переменные такими же, как имена методов.

Homunculus Reticulli 03.04.2020 20:10

У вас есть функция os.path.exists:

import os.path
os.path.exists(file_path)

Это возвращает True для файлов и каталогов, но вместо этого вы можете использовать

os.path.isfile(file_path)

чтобы проверить, является ли это конкретным файлом. Он следует символическим ссылкам.

Если причина, по которой вы проверяете, заключается в том, что вы можете сделать что-то вроде if file_exists: open_it(), безопаснее использовать try при попытке его открыть. При проверке и последующем открытии файл может быть удален или перемещен или что-то в этом роде между моментом проверки и попыткой его открытия.

Если вы не планируете сразу открывать файл, вы можете использовать os.path.isfile

Return True if path is an existing regular file. This follows symbolic links, so both islink() and isfile() can be true for the same path.

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

Что касается первого замечания (используйте "попробуйте", если проверьте перед открытием), к сожалению, это не сработает, если вы хотите открыть для добавления, будучи уверенным, что он существует раньше, поскольку режим 'a' будет создан, если не существует.

makapuf 20.06.2018 10:58

Обратите внимание, что FileNotFoundError был введен в Python 3. Если вам также необходимо поддерживать Python 2.7, а также Python 3, вы можете использовать вместо него IOError (который является подклассом FileNotFoundError) stackoverflow.com/a/21368457/1960959

scottclowe 29.03.2019 16:44

@makapuf Можно открыть на «обновление» (open('file', 'r+')) и дальше искать до конца.

kyrill 30.04.2019 20:45

Подождите, так pathlib2 <pathlib? pathlib предназначен для python3, верно? Я использовал pathlib2, думая, что он лучше.

theX 03.07.2020 00:26

@kyrill: открытие файла для добавления - это не то же самое, что открытие его для записи и поиска до конца: когда у вас есть одновременные писатели, они будут перезаписывать друг друга без 'a'.

hagello 20.11.2020 17:48

Дополнительно os.access():

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()

Это R_OK, W_OK и X_OK - это флаги для проверки разрешений (док).

В отличие от 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

Предпочитайте заявление о попытке. Это считается лучшим стилем и позволяет избежать условий гонки.

Не верьте мне на слово. Эта теория имеет множество подтверждений. Вот парочка:

Пожалуйста, добавьте лучшие источники в поддержку вашего утверждения.

BlueTrin 10.09.2015 12:09

Указанная ссылка «Избегание условий гонки» (поддержка разработчиков Apple) не поддерживает ваш ответ. Это касается только использования временных файлов, содержащих конфиденциальную информацию, в плохо спроектированных операционных системах, которые не помещают временные файлы / каталоги в изолированную среду с ограниченными разрешениями. В любом случае использование try...except не помогает решить проблему который.

jstine 28.09.2015 18:38

Проблема с этим методом заключается в том, что если у вас есть важный фрагмент кода, зависящий от файла, который не существует, включение его в предложение except: приведет к тому, что исключение, возникающее в этой части вашего кода, вызовет сбивающее с толку сообщение (возникла вторая ошибка во время обработки первого.)

Camion 24.05.2019 13:43

Вы можете попробовать это (безопаснее):

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] No such file or directory: 'whatever.txt')

Затем, в зависимости от результата, ваша программа может просто продолжать работать оттуда или вы можете закодировать, чтобы остановить ее, если хотите.

Исходный вопрос был задан для решения, которое не использует try.

rrs 23.04.2014 17:10

Этот ответ упускает из виду суть ОП. Проверка того, существует ли файл, - это не то же самое, что проверка возможности его открытия. Бывают случаи, когда файл действительно существует, но по разным причинам вы не можете его открыть.

Chris Johnson 17.02.2016 21:52

import os
path = /path/to/dir

root,dirs,files = os.walk(path).next()
if myfile in files:
   print "yes it exists"

Это полезно при проверке нескольких файлов. Или вы хотите выполнить пересечение / вычитание набора с существующим списком.

Это неверно по двум причинам: (1) os.walk находит все файлы в дереве каталогов - если пользователь хочет проверить наличие ./FILE, маловероятно, что он захочет рассматривать ./some/sub/folder/FILE как совпадение, что и делает ваше решение; и (2) ваше решение очень неэффективно по сравнению с простым вызовом os.path.isfile() в случае, когда есть много файлов ниже текущего каталога. В случае, если в дереве не существует подходящего имени файла без пути, ваш код перечислит каждый файл в дереве перед возвратом false.

Chris Johnson 14.06.2017 01:10

Используйте 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")

наличие нескольких условий, некоторые из которых являются лишними, является меньше ясным и явным.

wim 09.04.2013 09:45

Это тоже избыточно. Если файл не существует, os.access() вернет false.

user207421 13.03.2018 03:01

@EJP В Linux файлы могут существовать, но не доступны.

e-info128 17.07.2018 00:30

Поскольку у вас import os, вам не нужно снова использовать import os.path, поскольку он уже является частью os. Вам просто нужно импортировать os.path, если вы собираетесь использовать функции только из os.path, а не из самого os, чтобы импортировать меньшую вещь, но поскольку вы используете os.access и os.R_OK, второй импорт не нужен.

Jester 24.08.2018 16:10

Проверка наличия у пользователя прав доступа для чтения файла очень профессиональна. Часто данные находятся на локальном диске во время разработки и на сетевом ресурсе в продукте. Тогда это может привести к такой ситуации. Кроме того, код совершенно ясен, удобочитаем и понятен.

Martin Meeser 02.07.2020 10:04

Вам обязательно стоит использовать этот.

from os.path import exists

if exists("file") == True:
    print "File exists."
elif exists("file") == False:
    print "File doesn't exist."

Проголосовали за явное намерение помочь OP. Я не согласен со стилем кодирования, но это не повод для отрицания. Кроме того, этот пример на самом деле не самодостаточен, поскольку «Файл» C: \ Users **** \ Desktop \ datastore.py », строка 4 выводит« Файл существует ». ^ SyntaxError: неверный синтаксис»

Dmitry 27.04.2013 17:21

Это состояние гонки из-за повторения теста exists. Если файл создается после if, но до elif, ни одна ветвь не выполняется. Было бы лучше просто изменить это на else, чтобы, по крайней мере, сделать код детерминированным.

tripleee 22.08.2013 10:45

Это неверный ответ. os.path.exists возвращает true для вещей, которые не являются файлами, например каталогов. Это дает ложные срабатывания. См. Другие ответы, рекомендующие os.path.isfile.

Chris Johnson 03.08.2015 18:10

Это самый простой способ проверить, существует ли файл. Просто потому что файл существовал, когда вы отметили, не гарантия, что он будет там, когда вам нужно его открыть.

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")

Пока вы намереваетесь получить доступ к файлу, условие гонки существует, независимо от того, как построена ваша программа. Ваша программа не может гарантировать, что другой процесс на компьютере не изменил файл. Это то, что Эрик Липперт называет экзогенное исключение. Вы не можете избежать этого, предварительно проверив наличие файла.

Isaac Supeene 23.11.2014 21:37

@IsaacSupeene Лучшая практика - сделать окно (файловой) операции как можно меньшим с последующей надлежащей обработкой исключений.

un33k 28.07.2018 05:52

Не похоже, что есть значимая функциональная разница между try / except и isfile(), поэтому вам следует использовать тот, который имеет смысл.

Если вы хотите прочитать файл, если он существует, выполните

try:
    f = open(filepath)
except IOError:
    print 'Oh dear.'

Но если вы просто хотите переименовать файл, если он существует, и, следовательно, вам не нужно его открывать, выполните

if os.path.isfile(filepath):
    os.rename(filepath, filepath + '.old')

Если вы хотите записать в файл, если он не существует, выполните

# python 2
if not os.path.isfile(filepath):
    f = open(filepath, 'w')

# python 3, x opens for exclusive creation, failing if the file already exists
try:
    f = open(filepath, 'wx')
except IOError:
    print 'file already exists'

Другое дело, если вам нужна блокировка файлов.

Это неверный ответ. os.path.exists возвращает true для вещей, которые не являются файлами, например каталогов. Это дает ложные срабатывания. См. Другие ответы, рекомендующие os.path.isfile.

Chris Johnson 01.08.2015 16:54

В вашем третьем примере я создаю ссылку с именем filepath с правильным временем, а БАМ, вы перезаписываете целевой файл. Вы должны сделать open(filepath, 'wx') в блоке try...except, чтобы избежать проблемы.

spectras 24.08.2015 17:05

Во втором примере, по крайней мере, в Windows, вы получите OSError, если filepath + '.old' уже существует: «В Windows, если dst уже существует, OSError будет вызвана, даже если это файл; возможно, нет способа реализовать атомарное переименование. когда dst называет существующий файл. "

Tom Myddeltyn 24.05.2016 17:14

@TomMyddeltyn: Начиная с Python 3.3, os.replace переносимо выполняет тихую замену целевого файла (это идентично поведению os.rename в Linux) (ошибка возникает только в том случае, если конечное имя существует и является каталогом). Итак, вы застряли на 2.x, но у пользователей Py3 уже несколько лет есть хороший вариант.

ShadowRanger 29.11.2017 21:14

На примере rename: это все равно нужно делать с try / except. os.rename (или os.replace в современном Python) является атомарным; установка проверки и переименования приводит к ненужной гонке и дополнительным системным вызовам. Просто сделай try: os.replace(filepath, filepath + '.old') except OSError: pass

ShadowRanger 29.11.2017 21:17

Python 3.4+ имеет объектно-ориентированный модуль пути: pathlib. Используя этот новый модуль, вы можете проверить, существует ли такой файл:

import pathlib
p = pathlib.Path('path/to/file')
if p.is_file():  # or p.is_dir() to see if it is a directory
    # do stuff

Вы можете (и обычно должны) использовать блок try/except при открытии файлов:

try:
    with p.open() as f:
        # do awesome stuff
except OSError:
    print('Well darn.')

В модуле pathlib есть много интересных вещей: удобная подстановка подстановки, проверка владельца файла, более легкое объединение путей и т. д. Это стоит проверить. Если вы используете более старый Python (версия 2.6 или новее), вы все равно можете установить pathlib с помощью pip:

# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2

Затем импортируйте его следующим образом:

# Older Python versions
import pathlib2 as pathlib

Вы можете использовать pathlib.Path.exists, который охватывает больше случаев, чем is_file

Ryan Haining 12.10.2020 00:13

Вы можете написать предложение Брайана без 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

Вы можете использовать следующий открытый метод, чтобы проверить, существует ли файл + доступен для чтения:

file = open(inputFile, 'r')
file.close()

Это определенно вызывает исключение, если файла нет ...

Sam Dolan 20.02.2020 01:06

Если файл предназначен для открытия, вы можете использовать один из следующих способов:

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.

Chris Johnson 01.08.2015 16:55

также возникла проблема с ложным положением.

Zorglub29 20.05.2018 00:33
docs.python.org/3/library/os.path.html#os.path.existsК приведенному выше заявлению криса >>os.path.exists(path) > Return True if path refers to an existing path or an open file descriptor. Returns False for broken symbolic links. On some platforms, this function may return False if permission is not granted to execute os.stat() on the requested file, even if the path physically exists. Changed in version 3.3: path can now be an integer: True is returned if it is an open file descriptor, False otherwise. Changed in version 3.6: Accepts a path-like object.
JayRizzo 01.09.2018 02:24

Чтобы проверить, существует ли файл,

from sys import argv

from os.path import exists
script, filename = argv
target = open(filename)
print "file exists: %r" % exists(filename)

Exists не делает различий между файлом и каталогом. os.path.isfile - лучший способ проверить, существует ли файл.

Pavel Chernikov 23.08.2015 05:12

Вы можете использовать библиотеку "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.

Chris Johnson 01.08.2015 16:55

@Chris Johnson, функция os.path.exists () проверяет, существует ли путь в системе. ПУТЬ может быть КАТАЛОГОМ или ФАЙЛОМ. Он будет работать нормально в обоих случаях. Пожалуйста, попробуйте какой-нибудь пример

Pradip Das 02.08.2015 17:51

Итак, этот ответ работает. Большой. Iff - это не путь к файлу. В этом был вопрос? Нет.

Debosmit Ray 15.04.2016 02:33

По-разному. Если цель определения существования «файла» состоит в том, чтобы выяснить, существует ли уже путь (и, следовательно, не является путем, где новые данные могут быть сохранены без удаления другой информации), тогда exists в порядке. Если цель состоит в том, чтобы определить, безопасно ли открывать предположительно существующий файл, то критика оправдана и существует недостаточно точно. К сожалению, OP не указывает, какая цель является желаемой (и, вероятно, больше этого не будет).

starturtle 05.09.2017 14:24

Хотя я всегда рекомендую использовать операторы try и except, вот несколько возможностей для вас (мой личный фаворит - использование os.access):

  1. Попробуйте открыть файл:

    Открытие файла всегда проверяет его существование. Вы можете сделать такую ​​функцию:

    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
    
  2. Используйте 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
    
  3. Используйте os.access(path, mode):

    Это проверит, есть ли у вас доступ к файлу. Он проверит разрешения. На основе документации os.py, набрав os.F_OK, он проверит существование пути. Однако это создаст брешь в безопасности, поскольку кто-то может атаковать ваш файл, используя время между проверкой разрешений и открытием файла. Вместо этого вам следует перейти непосредственно к открытию файла, а не проверять его разрешения. (EAFP против LBYP). Если вы не собираетесь открывать файл после этого, а только проверяете его существование, вы можете использовать это.

    Во всяком случае, здесь:

    >>> import os
    >>> os.access("/is/a/file.txt", os.F_OK)
    True
    

Я также должен упомянуть, что есть два способа, которыми вы не сможете проверить существование файла. Либо проблема будет в permission denied, либо в no such file or directory. Если вы поймали IOError, установите IOError as e (как мой первый вариант), а затем введите print(e.args), чтобы вы могли, надеюсь, определить свою проблему. Я надеюсь, что это помогает! :)

if os.path.isfile(path_to_file):
    try: 
        open(path_to_file)
            pass
    except IOError as e:
        print "Unable to open file"

Raising exceptions is considered to be an acceptable, and Pythonic, approach for flow control in your program. Consider handling missing files with IOErrors. In this situation, an IOError exception will be raised if the file exists but the user does not have read permissions.

SRC: http://www.pfinn.net/python-check-if-file-exists.html

OP спросил, как проверить, существует ли файл. Возможно, файл существует, но вы не сможете его открыть. Поэтому использование открытия файла в качестве прокси для проверки того, существует ли файл, неверно: будет иметь ложноотрицательные результаты.

Chris Johnson 17.02.2016 21:58

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.

Chris Johnson 01.08.2015 16:56

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)

@ j6m8 да, isReadableFile(path,fileName) вернет True, если файл доступен и доступен для чтения процессу \ программе \ потоку

Khaled.K 09.08.2015 10:46

How do I check whether a file exists, using Python, without using a try statement?

Теперь, доступный начиная с Python 3.4, импортируйте и создайте экземпляр объекта Path с именем файла и проверьте метод is_file (обратите внимание, что он также возвращает True для символических ссылок, указывающих на обычные файлы):

>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False

Если вы используете Python 2, вы можете выполнить резервное копирование модуля pathlib из pypi, pathlib2 или иным образом проверить isfile из модуля os.path:

>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False

Вышеупомянутое, вероятно, является лучшим прагматичным прямым ответом здесь, но есть вероятность состояния гонки (в зависимости от того, что вы пытаетесь выполнить) и тот факт, что базовая реализация использует try, но Python использует try везде в своем выполнение.

Поскольку Python везде использует try, на самом деле нет причин избегать реализации, в которой он используется.

Но остальная часть этого ответа пытается учесть эти предостережения.

Более длинный и педантичный ответ

Доступен начиная с Python 3.4, используйте новый объект Path в pathlib. Обратите внимание, что .exists не совсем правильный, потому что каталоги не являются файлами (за исключением того, что в unix смысле все является файлом).

>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True

Итак, нам нужно использовать is_file:

>>> root.is_file()
False

Вот справка по is_file:

is_file(self)
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).

Итак, давайте получим файл, который, как мы знаем, является файлом:

>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True

По умолчанию NamedTemporaryFile удаляет файл при закрытии (и автоматически закрывается, когда на него больше не существует ссылок).

>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False

Однако если вы углубитесь в реализация, вы увидите, что is_file использует try:

def is_file(self):
    """
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).
    """
    try:
        return S_ISREG(self.stat().st_mode)
    except OSError as e:
        if e.errno not in (ENOENT, ENOTDIR):
            raise
        # Path doesn't exist or is a broken symlink
        # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
        return False

Условия гонки: почему нам нравится пробовать

Нам нравится try, потому что он избегает условий гонки. С try вы просто пытаетесь прочитать свой файл, ожидая, что он там есть, а если нет, вы перехватываете исключение и выполняете любое возможное резервное поведение.

Если вы хотите проверить, существует ли файл, прежде чем пытаться его прочитать, и вы, возможно, удаляете его, а затем используете несколько потоков или процессов, или другая программа знает об этом файле и может его удалить - вы рискуете состояние гонки, если вы проверяете, что он существует, потому что вы тогда гонки, чтобы открыть его до того, как его условие (его существование) изменится.

Условия гонки очень трудно отлаживать, потому что есть очень маленькое окно, в котором они могут привести к сбою вашей программы.

Но если это ваша мотивация, вы может получите значение оператора try с помощью диспетчера контекста suppress.

Избежание условий гонки без запроса try: suppress

Python 3.4 предоставляет нам диспетчер контекста suppress (ранее диспетчер контекста 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)

из документы:

os.path.isfile(path)

Return True if path is an existing regular file. This follows symbolic links, so both islink() and isfile() can be true for the same path.

Но если вы изучите источник этой функции, вы увидите, что она действительно использует оператор try:

# This follows symbolic links, so both islink() and isdir() can be true
# for the same path on systems that support symlinks
def isfile(path):
    """Test whether a path is a regular file"""
    try:
        st = os.stat(path)
    except os.error:
        return False
    return stat.S_ISREG(st.st_mode)
>>> OSError is os.error
True

Все, что он делает, это использует заданный путь, чтобы увидеть, может ли он получить статистику по нему, перехватывая OSError, а затем проверяя, является ли это файлом, если он не вызывает исключение.

Если вы собираетесь что-то сделать с файлом, я бы посоветовал напрямую попробовать это с помощью try, за исключением того, чтобы избежать состояния гонки:

try:
    with open(path) as f:
        f.read()
except OSError:
    pass

os.access

Для Unix и Windows доступен os.access, но для использования необходимо передавать флаги, и он не делает различий между файлами и каталогами. Это больше используется для проверки, имеет ли реальный вызывающий пользователь доступ в среде с повышенными привилегиями:

import os
os.access(path, os.F_OK)

Он также страдает теми же проблемами состояния гонки, что и isfile. Из документы:

Note: Using access() to check if a user is authorized to e.g. open a file before actually doing so using open() creates a security hole, because the user might exploit the short time interval between checking and opening the file to manipulate it. It’s preferable to use EAFP techniques. For example:

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()
return "some default data"

is better written as:

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:

Personally, I prefer this one because under the hood, it calls native APIs (via "${PYTHON_SRC_DIR}/Modules/posixmodule.c"), but it also opens a gate for possible user errors, and it's not as Pythonic as other variants:

В этом ответе говорится, что он предпочитает не-питонический, подверженный ошибкам метод без каких-либо оснований. Кажется, это побуждает пользователей использовать низкоуровневые API, не понимая их.

Он также создает диспетчер контекста, который, безоговорочно возвращая True, позволяет всем исключениям (включая KeyboardInterrupt и SystemExit!) Проходить без уведомления, что является хорошим способом скрыть ошибки.

Похоже, это побуждает пользователей применять неэффективные методы.

Вот однострочная команда Python для среды командной строки Linux. Я нахожу это ОЧЕНЬ УДОБНЫМ, так как я не такой горячий парень с Bash.

python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"

Надеюсь, это поможет.

Однострочная проверка в bash: [ -f "${file}" ] && echo "file found" || echo "file not found" (то же самое, что и if [ ... ]; then ...; else ...; fi).

flotzilla 01.10.2015 10:48

В 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 вместо модуля os в python3 для этой проверки?

Joko 25.02.2016 11:55

pathlib - это ООП-решение на Python для путей. Вы можете сделать с ним гораздо больше. Если вам просто нужно проверить наличие, преимущество не так велико.

KaiBuxe 25.02.2016 13:44

Я являюсь автором пакета, который существует уже около 10 лет, и в нем есть функция, которая напрямую решает этот вопрос. По сути, если вы работаете в системе, отличной от Windows, она использует Popen для доступа к find. Однако, если вы работаете в Windows, он реплицирует find с эффективным обходом файловой системы.

Сам код не использует блок try… за исключением определения операционной системы и, таким образом, направляет вас к «Unix» -стилю find или вручную собранному find. Временные тесты показали, что try быстрее определяет ОС, поэтому я использовал ее (но нигде больше).

>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']

И документ…

>>> print pox.find.__doc__
find(patterns[,root,recurse,type]); Get path to a file or directory

    patterns: name or partial name string of items to search for
    root: path string of top-level directory to search
    recurse: if True, recurse down from root directory
    type: item filter; one of {None, file, dir, link, socket, block, char}
    verbose: if True, be a little verbose about the search

    On some OS, recursion can be specified by recursion depth (an integer).
    patterns can be specified with basic pattern matching. Additionally,
    multiple patterns can be specified by splitting patterns with a ';'
    For example:
        >>> find('pox*', root='..')
        ['/Users/foo/pox/pox', '/Users/foo/pox/scripts/pox_launcher.py']

        >>> find('*shutils*;*init*')
        ['/Users/foo/pox/pox/shutils.py', '/Users/foo/pox/pox/__init__.py']

>>>

Реализация, если вы хотите посмотреть, находится здесь: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190

Вы можете использовать os.listdir, чтобы проверить, находится ли файл в определенном каталоге.

import os
if 'file.ext' in os.listdir('dirpath'):
    #code

не будет работать в Windows, поскольку файловая система не чувствительна к регистру. И очень неэффективно, потому что сканирует весь каталог.

Jean-François Fabre 07.01.2017 15:24

Добавление еще одного небольшого изменения, которое не совсем отражено в других ответах.

Это будет обрабатывать случай, когда 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).

Shahbaz 05.01.2017 01:50

Вы должны быть осторожны с return x в случае с if (x). Python будет считать пустую строку False, и в этом случае мы вернем пустую строку вместо bool. Цель этой функции - всегда возвращать bool.

Marcel Wilson 05.01.2017 20:08

Истинный. Однако в данном случае x - это os.path.isfile(..), так что это уже bool.

Shahbaz 05.01.2017 20:10

os.path.isfile(None) вызывает исключение, поэтому я добавил проверку if. Я, вероятно, мог бы просто обернуть это в try / except, но я чувствовал, что так это более явно.

Marcel Wilson 05.01.2017 20:13

return file_path and os.path.isfile(file_path)

Peter Wood 06.04.2017 13:35

Тестирование файлов и папок с помощью 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

How do I check whether a file exists, without using the try statement?

В 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 здесь

Примечание: Однако этот подход никоим образом не заблокирует файл, и поэтому ваш код может стать уязвимым для ошибок "время проверки ко времени использования" (ТОКТУ).

Таким образом, создание исключений считается приемлемым и питоническим подходом для управления потоком в вашей программе. И следует рассмотреть возможность обработки отсутствующих файлов с помощью IOErrors, а не операторов if (просто совет).

Если вы уже импортировали NumPy для других целей, тогда нет необходимости импортировать другие библиотеки, такие как pathlib, os, paths и т. д.

import numpy as np
np.DataSource().exists("path/to/your/file")

Это вернет истину или ложь в зависимости от его существования.

Дата: 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']}

Убедитесь, что файл или каталог существует

Вы можете воспользоваться этими тремя способами:

Note1: The os.path.isfile used only for files

import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists

Note2: The os.path.exists used for both files and directories

import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists

The pathlib.Path method (included in Python 3+, installable with pip for Python 2)

from pathlib import Path
Path(filename).exists()

import os

# for testing purpose args defaulted to current folder & file. 
# returns True if file found
def file_exists(FOLDER_PATH='../', FILE_NAME=__file__):
    return os.path.isdir(FOLDER_PATH) \
        and os.path.isfile(os.path.join(FOLDER_PATH, FILE_NAME))

В основном это проверка папки, затем проверка файлов с правильным разделителем каталогов с использованием os.path.join.

Вероятно, это не нужно, но если это так, вот код

import os

def file_exists(path, filename):
    for file_or_folder in os.listdir(path):
        if file_or_folder == filename:
            return True
    return False

Это слишком сложно и излишне тратит ресурсы. Почему? (Особенно после того, как уже есть куча полезных ответов ...)

moi 08.10.2019 15:46

Методы существуют() и is_file () объекта 'Дорожка' могут использоваться для проверки того, существует ли данный путь и является ли он файлом.

Программа Python 3 для проверки существования файла:

# File name:  check-if-file-exists.py

from pathlib import Path

filePath = Path(input("Enter path of the file to be found: "))

if filePath.exists() and filePath.is_file():
    print("Success: File exists")
else:
    print("Error: File does not exist")

Выход:

$ python3 check-if-file-exists.py

Enter path of the file to be found: /Users/macuser1/stack-overflow/index.html

Success: File exists

$ python3 check-if-file-exists.py

Enter path of the file to be found: hghjg jghj

Error: File does not exist

используйте os.path.exists (), чтобы узнать, существует ли файл.

path = '/home/ie/SachinSaga/scripts/subscription_unit_reader_file/'
def file_check_at_location(filename):
    return os.path.exists(path + str(filename).replace(' ',''))


file_name = "dummy.txt"
responce = file_check_at_location(file_name)

if responce:
   print('file found at location')
else:
   print('file not found at location')

Любые пояснения, почему этот ответ отклонен? Os.path.exists () - это не решение?

Yash Nag 29.09.2020 01:51

@YashNag из другого ответа: В отличие от isfile(), exists() вернет True для каталогов.

Pranav Hosangadi 30.09.2020 17:44

Обычно это то, что вам нужно, а не isfile, поскольку вопрос «существует ли файл» обычно действительно спрашивает, существует ли путь, а не является ли это файлом. Пожалуйста, прекратите голосовать против полезной информации.

Glenn Maynard 11.02.2021 03:31

Почему вы заменяете пробелы в имени файла? Теперь вы можете проверить, существует ли файл, отличный от того, о котором вас спрашивают. Почему вы вызываете на нем str ()? Если это еще не строка, определяющая файл, вероятно, что-то очень не так с тем, как функция вызывается.

Ceisc 12.03.2021 01:21

Используйте следующий код:

def findfile(self, filepath)
  flag = false
  for filename in os.listdir(filepath)
    if filename == "your file name"
      flag = true
      break
    else 
      print("no file found")
  if (flag == true)
    return true
  else 
    return false

Это почти то же самое, что предлагает этот ответ, но с избыточной переменной flag. Кроме того, true и false должны быть написаны с заглавной буквы. См. Встроенные константы.

Georgy 11.12.2020 12:29

TL; DR Чтобы быстро проверить наличие файла или папки, используйте модуль Дорожка. Вот однострочный код (после импорта)!

from pathlib import Path
if Path("myfile.txt").exists(): # works for both file and folders
    # do stuffs...

Модуль pathlib был представлен в Python 3.4, поэтому вам понадобится Python 3.4+, эта библиотека значительно упрощает вашу жизнь и удобна в использовании, вот еще документация об этом (https://docs.python.org/3/library/pathlib.html).

Кстати, если вы собираетесь повторно использовать путь, то лучше назначить его переменной

так станет

from pathlib import Path
p = Path("loc/of/myfile.txt")
if p.exists(): # works for both file and folders
    # do stuffs...

Другие вопросы по теме