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

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

17.09.2008 12:55:00
Похоже, это классическая дискуссия EAFP против LBYL, см., Например, следующий вопрос: stackoverflow.com/questions/1835756/using-try-vs-if-in-python
matth 30.10.2019 08:20:58
30 ОТВЕТОВ
import os.path

if os.path.isfile(filepath):
616
21.06.2017 20:33:46
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
282
2.06.2018 20:52:01
Как правило, не рекомендуется именовать переменные так же, как имена методов.
Homunculus Reticulli 3.04.2020 17:10:44

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

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

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

os.path.isfile(file_path)

проверить, если это файл специально. Это следует за символическими ссылками.

2083
19.10.2018 08:58:59

Если причина, по которой вы проверяете, заключается в том, что вы можете сделать что-то подобное 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
5082
13.05.2019 10:40:43
Что касается первого замечания (используйте «попробовать», если проверка перед открытием), к сожалению, это не будет работать, если вы хотите открыть для добавления, будучи уверенным, что он существует раньше, так как режим «а» будет создан, если не существует.
makapuf 20.06.2018 07:58:09
Обратите внимание, что это FileNotFoundErrorбыло введено в Python 3. Если вам также необходимо поддерживать Python 2.7 и Python 3, вы можете использовать IOErrorвместо этого (какие FileNotFoundErrorподклассы) stackoverflow.com/a/21368457/1960959
scottclowe 29.03.2019 13:44:15
@makapuf Вы можете открыть его для «обновления» ( open('file', 'r+')) и затем искать до конца.
kyrill 30.04.2019 17:45:44
@kyrill open-and-seek-to-the end - это не то же самое, что open-for-append (по крайней мере, в системах posix). «режим добавления» всегда будет правильно записывать в конец файла, даже если другие вещи изменяют файл между моментом его открытия и моментом записи. Открытие для записи / обновления и поиск до конца может повредить данные файла, если несколько файлов пытаются одновременно записать один и тот же файл. К сожалению, я полагаю, что единственный безопасный для условий гонки способ открыть-для-добавления, при условии, что файл существует первым, - это использовать подпрограммы os.open () более низкого уровня (O_APPEND без O_CREAT).
Foogod 19.02.2020 17:31:34
Хорошая точка зрения. Хотя, если несколько «вещей» пытаются записать в один и тот же файл одновременно без какой-либо синхронизации, возможно, это все равно будет повреждено. А если вы используете синхронизацию, вам не нужно беспокоиться о состоянии гонки.
kyrill 19.02.2020 20:44:53

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

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

Быть R_OK, W_OKи X_OKфлаги для проверки разрешений ( doc ).

35
4.05.2016 15:24:02

В отличие от 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
948
3.03.2020 17:45:09

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

Не верь мне на слово. Есть много поддержки этой теории. Вот пара:

124
28.04.2014 01:01:59
Пожалуйста, добавьте лучшие источники в поддержку вашего заявления.
BlueTrin 10.09.2015 09:09:37
Ссылка "Избегать условий гонки" (поддержка Apple Dev) не поддерживает ваш ответ. Это касается только использования временных файлов, которые содержат конфиденциальную информацию в плохо спроектированных операционных системах, которые неправильно ограничивают временные файлы / каталоги песочницей из-за ограниченных разрешений. Использование try...exceptне помогает решить эту проблему в любом случае.
jstine 28.09.2015 15:38:00
Проблема этого метода заключается в том, что если у вас есть важный фрагмент кода, зависящий от несуществующего файла, то включение его в except:предложение приведет к тому, что исключение, возникающее в этой части кода, вызовет сбивающее с толку сообщение (вторая ошибка возникает во время обработка первого).
Camion 24.05.2019 10:43:34

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

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

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

58
27.05.2017 00:43:51
Оригинальный вопрос просил решение, которое не используетtry
rrs 23.04.2014 13:10:01
Этот ответ не попадает в точку ОП. Проверка наличия файла - это не то же самое, что проверка возможности его открытия. В некоторых случаях файл существует, но по разным причинам его нельзя открыть.
Chris Johnson 17.02.2016 18:52:12
import os
path = /path/to/dir

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

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

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

Используйте 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")
300
26.03.2020 11:35:27
Наличие нескольких условий, некоторые из которых являются излишними, менее ясно и явно.
wim 9.04.2013 05:45:27
Это также избыточно. Если файл не существует, os.access()вернет false.
user207421 13.03.2018 00:01:19
@EJP В Linux файлы могут существовать, но не доступны.
e-info128 16.07.2018 21:30:18
Поскольку вы import os, вам не нужно import os.pathснова, так как он уже является частью os. Вам просто нужно импортировать, os.pathесли вы собираетесь использовать функции os.pathтолько из osсебя, а не из себя, чтобы импортировать меньшую вещь, но по мере использования os.accessи os.R_OK, второй импорт не нужен.
Jester 24.08.2018 13:10:26

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

from os.path import exists

if exists("file") == True:
    print "File exists."
elif exists("file") == False:
    print "File doesn't exist."
2
4.04.2013 18:21:11
Проголосовал из-за явного намерения помочь ФП. Я не согласен со стилем кодирования, но это не повод для понижения. Кроме того, этот пример не является самодостаточным, поскольку «Файл» C: \ Users **** \ Desktop \ datastore.py », строка 4, печать« Файл существует. »^ SyntaxError: неверный синтаксис»
Dmitry 27.04.2013 13:21:56
Это имеет состояние гонки из-за повторения existsтеста. Если файл создан после, ifно прежде elif, ни одна ветвь не будет взята. Было бы лучше просто изменить это, чтобы, elseпо крайней мере, сделать код детерминированным.
tripleee 22.08.2013 06:45:45
Этот ответ неверен. os.path.existsвозвращает true для вещей, которые не являются файлами, например, для каталогов. Это дает ложные срабатывания. Смотрите другие ответы, которые рекомендуют os.path.isfile.
Chris Johnson 3.08.2015 15:10:58

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

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")
153
14.01.2018 04:07:53
Пока вы намереваетесь получить доступ к файлу, условие гонки существует , независимо от того, как построена ваша программа. Ваша программа не может гарантировать, что другой процесс на компьютере не изменил файл. Эрик Липперт называет это экзогенным исключением . Вы не можете избежать этого, предварительно проверив существование файла.
Isaac Supeene 23.11.2014 18:37:59
@IsaacSupeene Лучшая практика - сделать окно операции (файла) как можно
un33k 28.07.2018 02:52:48

Не похоже, что между 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'

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

65
25.08.2015 03:12:24
Этот ответ неверен. os.path.existsвозвращает true для вещей, которые не являются файлами, например, для каталогов. Это дает ложные срабатывания. Смотрите другие ответы, которые рекомендуют os.path.isfile.
Chris Johnson 1.08.2015 13:54:35
В третьем примере я создаю ссылку filepathс правильным временем, а BAM перезаписывает целевой файл. Вы должны сделать open(filepath, 'wx')в try...exceptблоке, чтобы избежать проблемы.
spectras 24.08.2015 14:05:09
Во втором примере, по крайней мере, в Windows, вы получите OSErrorif, если он filepath + '.old'уже существует: «В Windows, если dst уже существует, OSError будет вызываться, даже если это файл; может быть невозможно реализовать атомарное переименование при dst называет существующий файл. "
Tom Myddeltyn 24.05.2016 14:14:04
@TomMyddeltyn: Начиная с Python 3.3,os.replace переносимо выполняет автоматическую замену файла назначения (он идентичен os.renameповедению Linux) (он только выдает ошибки, если имя назначения существует и является каталогом). Итак, вы застряли на 2.x, но у пользователей Py3 был хороший выбор уже несколько лет.
ShadowRanger 29.11.2017 18:14:56
На renameпримере: это все еще должно быть сделано с try/ except. os.rename(или os.replaceна современном Python) является атомарным; проверка его, а затем переименование приводит к ненужной гонке и дополнительным системным вызовам. Просто сделайtry: os.replace(filepath, filepath + '.old') except OSError: pass
ShadowRanger 29.11.2017 18:17:31

В 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
143
4.12.2017 14:45:12

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

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

file = open(inputFile, 'r')
file.close()
8
3.02.2020 16:26:28
Это определенно создает исключение, если файла нет ...
Sam Dolan 19.02.2020 22:06:50

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

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!')

ОБНОВИТЬ

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

35
21.02.2020 13:28:05
Этот ответ неверен. os.path.existsвозвращает true для вещей, которые не являются файлами, например, для каталогов. Это дает ложные срабатывания. Смотрите другие ответы, которые рекомендуют os.path.isfile.
Chris Johnson 1.08.2015 13:55:01
получил ложную положительную проблему также.
Zorglub29 19.05.2018 21:33:55
docs.python.org/3/library/os.path.html#os.path.exists К приведенному выше заявлению от chris >> os.path.exists (path)> верните True, если path ссылается на существующий путь или открытый дескриптор файла. Возвращает False для неработающих символических ссылок. На некоторых платформах эта функция может возвращать False, если не предоставлено разрешение на выполнение os.stat () для запрошенного файла, даже если путь физически существует. Изменено в версии 3.3: путь теперь может быть целым числом: True возвращается, если это дескриптор открытого файла, False в противном случае. Изменено в версии 3.6: Принимает объект типа пути.
JayRizzo 31.08.2018 23:24:22

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

from sys import argv

from os.path import exists
script, filename = argv
target = open(filename)
print "file exists: %r" % exists(filename)
6
17.10.2014 21:25:30
Exists не делает различий между файлом и каталогом. os.path.isfile - лучший способ проверить, существует ли файл.
Pavel Chernikov 23.08.2015 02:12:50

Вы можете использовать библиотеку "OS" Python:

>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt") 
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False
11
27.05.2017 00:49:25
Этот ответ неверен. os.path.existsвозвращает true для вещей, которые не являются файлами, например, для каталогов. Это дает ложные срабатывания. Смотрите другие ответы, которые рекомендуют os.path.isfile.
Chris Johnson 1.08.2015 13:55:13
@Chris Johnson, функция os.path.exists () проверяет, существует ли путь в системе. ПУТЬ может быть КАТАЛОГОМ или ФАЙЛОМ. Это будет хорошо работать в обоих случаях. Пожалуйста, попробуйте какой-нибудь пример
Pradip Das 2.08.2015 14:51:41
Итак, этот ответ работает. Отлично. Если путь не путь к файлу. О чем был вопрос? Нет.
Debosmit Ray 14.04.2016 23:33:56
По-разному. Если цель определения существования «файла» состоит в том, чтобы выяснить, существует ли уже путь (и, следовательно, не является ли он путем, в котором новые данные могут быть сохранены без удаления другой информации), то existsэто нормально. Если цель состоит в том, чтобы определить, безопасно ли открывать предположительно существующий файл, то критика оправдана и существует недостаточно точно. К сожалению, ОП не определяет, какая цель является желаемой (и, вероятно, больше не будет).
starturtle 5.09.2017 11:24:42

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

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

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

    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
  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его, он проверит наличие пути. Однако использование этого создаст дыру в безопасности, поскольку кто-то может атаковать ваш файл, используя время между проверкой прав доступа и открытием файла. Вместо этого вам следует перейти непосредственно к открытию файла вместо проверки его прав доступа. ( ЭСПЦ против 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)чтобы вы могли надеяться определить вашу проблему. Я надеюсь, что это помогает! :)

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

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

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

20
18.07.2015 17:41:08
ОП спросил, как проверить, существует ли файл. Файл может существовать, но вы не можете его открыть. Поэтому использование открытия файла в качестве прокси-сервера для проверки, существует ли файл, является неправильным: будет иметь ложные отрицания.
Chris Johnson 17.02.2016 18:58:54
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.

86
16.05.2017 16:36:46
Этот ответ неверен. os.path.existsвозвращает true для вещей, которые не являются файлами, например, для каталогов. Это дает ложные срабатывания. Смотрите другие ответы, которые рекомендуют os.path.isfile.
Chris Johnson 1.08.2015 13:56:22
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)
9
8.10.2015 21:22:53
@ j6m8 да, isReadableFile(path,fileName)вернется, Trueесли файл доступен и читается процессом \ program \ thread
Khaled.K 9.08.2015 07:46:31

Как проверить, существует ли файл с использованием 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!), Что является хорошим способом скрыть ошибки.

Это, кажется, поощряет пользователей принимать плохие методы.

118
25.02.2018 20:45:39

Вот 1-строчная команда Python для среды командной строки Linux. Я нахожу это ОЧЕНЬ ХЕНДИ, так как я не такой крутой парень из Баша.

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

Я надеюсь, что это полезно.

14
29.08.2015 16:15:29
Однострочная проверка в bash: [ -f "${file}" ] && echo "file found" || echo "file not found"(что совпадает с if [ ... ]; then ...; else ...; fi).
flotzilla 1.10.2015 07:48:29

В 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():
    ...
71
27.05.2017 01:00:22
Могу я спросить: в чем преимущество использования модуля 'pathlib' вместо модуля 'os' в python3 для этой проверки?
Joko 25.02.2016 08:55:33
pathlibявляется ООП-решением Python для путей. Вы можете сделать намного больше с этим. Если вам просто нужно проверить существование, преимущество не так велико.
KaiBuxe 25.02.2016 10:44:49

Я являюсь автором пакета, который существует уже около 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

16
27.05.2017 00:59:52

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

import os
if 'file.ext' in os.listdir('dirpath'):
    #code
4
8.06.2016 12:45:32
не будет работать в Windows, так как файловая система не чувствительна к регистру. И очень неэффективно, потому что сканирует весь каталог.
Jean-François Fabre♦ 7.01.2017 12:24:21

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

Это будет обрабатывать случай 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):
15
7.04.2017 16:10:59
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 4.01.2017 22:50:16
Вы должны быть осторожны return xв случае if (x). Python будет рассматривать пустую строку False, в этом случае мы будем возвращать пустую строку вместо bool. Цель этой функции - всегда возвращать bool.
Marcel Wilson 5.01.2017 17:08:43
Правда. В этом случае , однако, xэто os.path.isfile(..)так уже BOOL.
Shahbaz 5.01.2017 17:10:24
os.path.isfile(None)вызывает исключение, поэтому я добавил проверку if. Я мог бы, вероятно, просто обернуть это в попытку / за исключением, но я чувствовал, что это было более явно таким образом.
Marcel Wilson 5.01.2017 17:13:10
return file_path and os.path.isfile(file_path)
Peter Wood 6.04.2017 10:35:01

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