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

avatar
spence91
17 сентября 2008 в 12:55
4467736
42
6278

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

Источник
Charlie Parker
6 августа 2020 в 19:40
8

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

Ответы (42)

avatar
Andrew
10 мая 2021 в 16:42
30

Проще всего это сделать с помощью

import os

if os.path.exists(FILE):
  # file exists
  pass
else:
  # file does not exists
  pass

из библиотеки ОС, а ФАЙЛ - относительный путь. В Windows это может или не работать, и вам, возможно, придется использовать путь освобождения, выполнив os.path.exists(os.path.join(os.path.abspath('./'), FILE)), где FILE по-прежнему является относительным путем плюс имя файла

avatar
Abhimanyu Sharma
16 апреля 2021 в 05:21
22

Вы можете использовать os.path.exists ():

import os
print(os.path.exists("file"))

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

avatar
masterofallthings
7 апреля 2021 в 20:26
2

Другой возможный вариант - проверить, находится ли имя файла в каталоге с помощью os.listdir ()

import os
if 'foo.txt' in os.listdir():
    # Do things

это вернет истину, если это так, и ложь, если нет

avatar
Memin
23 января 2021 в 09:48
28

TL; DR с одной строкой кода --- Keep It Simple

Чтобы проверить наличие файла или папки , используйте модуль Путь .

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...
bravhek
25 июня 2021 в 21:38
0

Имейте в виду, что это возвращает True, если файл отсутствует, но путь к файлу существует. Если вас действительно интересует вопрос, существует ли файл или нет, вам следует использовать p.is_file ()

avatar
Devbrat Shukla
12 мая 2020 в 14:35
4

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

def fileAtLocation(filename,path):
    return os.path.exists(path + filename)
 

filename="dummy.txt"
path = "/home/ie/SachinSaga/scripts/subscription_unit_reader_file/"


if fileAtLocation(filename,path):
   print('file found at location..')
else:
   print('file not found at location..')
Yash Nag
28 сентября 2020 в 22:51
0

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

Pranav Hosangadi
30 сентября 2020 в 14:44
3

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

Glenn Maynard
11 февраля 2021 в 00:31
1

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

Ceisc
11 марта 2021 в 22:21
0

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

Devbrat Shukla
13 марта 2021 в 15:54
0

Спасибо за отзыв. Я обновил свой ответ.

tdelaney
15 сентября 2021 в 06:54
1

@GlennMaynard - Нет, вы проверяете наличие файла, потому что хотите что-то сделать с файлом (возможно, прочитать его, возможно, создать). Наличие каталога с таким же именем - проблема. Обычно вы хотите протестировать оба, чтобы избежать ошибок.

avatar
Gopinath
26 января 2020 в 23:28
8

exists () и 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

Введите путь к файлу, который нужно найти: /Users/macuser1/stack-overflow/index.html

Успешно: Файл существует

$ python3 check-if-file-exists.py

Введите путь к файлу, который нужно найти: hghjg jghj

Ошибка: Файл не существует

avatar
Vimal Maheedharan
31 октября 2018 в 13:22
5
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 .

avatar
Ali Hallaji
4 марта 2018 в 06:24
18

Проверить, существует ли файл или каталог

Вы можете воспользоваться следующими тремя способами:

Примечание 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+, устанавливается с помощью pip для Python 2)

from pathlib import Path
Path(filename).exists()
avatar
AbstProcDo
4 декабря 2017 в 08:51
54

Дата: 04.12.2017

Все возможные решения перечислены в других ответах.

Интуитивно понятный и спорный способ проверить, существует ли файл, выглядит следующим образом:

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']}
avatar
durjoy
10 августа 2017 в 05:50
21

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

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

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

avatar
CristiFati
20 июня 2017 в 19:28
264

Хотя почти все возможные способы были перечислены в (по крайней мере, в одном из) существующих ответов (например, Python 3.4 был добавлен конкретный материал), я постараюсь сгруппировать все вместе.

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

Описание проблемы :

  1. Проверить файл ( спорно : также папка ("специальный" файл)?) Наличие
  2. Не используйте попробуйте / кроме / <383842401538> / <383842401538> / <383842401538> > наконец блоки

Возможные решения :

  1. [Python 3]: os.path. существует ( путь ) (также проверьте другие члены семейства функций, такие как <os.path.isfile4015338>, <3538> 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
        

    это просто попытка / , кроме блок вокруг stat738 [os15> .4240> > ( путь, *, dir_fd = None, follow_symlinks = True ) . Итак, ваш код попробуйте / кроме бесплатно, но ниже в стеке кадров есть (по крайней мере 384021538) > такой блок. Это также относится к другим функциям ( включая os.path.isfile).

    1.1. [Python 3]: путь. is_file ()

    • Это более изящный (и более python ic) способ обработки путей, но
    • Под капотом он делает в точности то же самое ( 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
      
  2. [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. подавить ( * исключения ) - который был специально разработан для <19401542> - который был специально разработан для <19401542> - который был специально разработан для <19401542> подавление исключений


    Но, похоже, они обертки над попробуйте / кроме <38424015534> кроме <38424015534> кроме <38424015532>, кроме<38424015532> > / окончательно блоки, как [Python 3]: с с с оператором <540>

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

  3. Функции обхода файловой системы (и поиск результатов для соответствующих элементов)


    Поскольку эти итерации по папкам (в большинстве случаев) неэффективны для нашей проблемы (есть исключения, например, без подстановочных знаков glob bing - как указал @ShadowRanger), поэтому Я не собираюсь на них настаивать. Не говоря уже о том, что в некоторых случаях может потребоваться обработка имени файла.

  4. [Python 3]: os. доступ ( путь, режим, *, dir_fd = None, Effective_ids = False, follow_symlinks = True, чье поведение <015>) <4673> близок к os.path.exists (на самом деле он шире, в основном из-за 2 аргумента nd )

    os.access("/tmp", os.F_OK)

    Поскольку я также работаю в C , я также использую этот метод, потому что внутри он вызывает собственный API s (снова через <383842401570 > "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c" ), но он также открывает ворота для возможных ошибок пользователя , и это не так Python ic, как другие варианты . Итак, как правильно заметил @AaronHall, не используйте его, если не знаете, что делаете:

    Примечание : вызов собственных API также возможен через [Python 3]: ctypes <3815424015733> - Библиотека сторонних функций Python734 , но в большинстве случаев все сложнее.

    (Win специфично): Начиная с vcruntime * ( msvcr * экспортирует msvcr * <384015742> > [MS.Docs]: _access, _waccess, а также семейство функций, вот пример:

    Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\cmd.exe", os.F_OK)
    0
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\cmd.exe.notexist", os.F_OK)
    -1
    

    Примечания :

    • Хотя это не очень хорошая практика, я использую os.F_OK в вызове, но это просто для ясности (его значение 0 )
    • Я использую _waccess , чтобы тот же код работал на Python3 и Python2 (несмотря на различия , связанные с unicode, связанные с их)
    • Хотя это нацелено на очень конкретную область, об этом не упоминалось ни в одном из предыдущих ответов


    Аналог Lnx ( Ubtu (16 x64) ):

    Python 3.5.2 (default, Nov 17 2016, 17:05:23)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp", os.F_OK)
    0
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp.notexist", os.F_OK)
    -1
    

    Примечания :

    • Вместо жесткого кодирования пути libc ( "/lib/x86_64-linux-gnu/libc.so.6" ), который может (и, скорее всего, будет) варьироваться в зависимости от систем, Ни один (или пустая строка) не может быть передан в конструктор CDLL ( ctypes.CDLL(None).access(b"/tmp", os.F_OK) ). Согласно [man7]: DLOPEN (3):

      Если имя_файла равно ПУСТО (NULL), то возвращаемый дескриптор предназначен для основного программа. При передаче dlsym () этот дескриптор вызывает поиск символ в основной программе, за которым следуют все общие объекты, загруженные в запуск программы, а затем все общие объекты, загруженные dlopen () с флаг RTLD_GLOBAL .

      • Основная (текущая) программа ( python ) связана с libc , поэтому ее символы (включая доступ ) будут загружены
      • С этим нужно обращаться осторожно, поскольку доступны такие функции, как main , Py_Main и (все) другие; вызов их может иметь катастрофические последствия (для текущей программы)
      • Это также не относится к Win (но это не такая уж большая проблема, поскольку msvcrt.dll находится в "% SystemRoot% \ System32" , который по умолчанию находится в % PATH% ). Я хотел пойти дальше и воспроизвести это поведение на Win (и отправить патч), но, как оказалось, [MS.Docs]: функция GetProcAddress "видит" только экспортировал символы , поэтому, если кто-то не объявляет функции в основном исполняемом файле как __declspec(dllexport) (зачем вообще обычный человек?), Основная программа загружается, но в значительной степени непригодна для использования
  5. Установите сторонний модуль с возможностями файловой системы

    Скорее всего, будет полагаться на один из способов, описанных выше (возможно, с небольшими изменениями).
    Одним из примеров может быть (опять же, Win специфично) [GitHub]: mhammond / pywin32 - Python для Windows (pywin32) Extensions, который является <40> Python648 <40> > оболочка для WINAPI s.

    Но, поскольку это больше похоже на обходной путь, я останавливаюсь на этом.

  6. Другой (неубедительный) обходной путь ( gainarie ) - это (как я люблю его называть) подход sysadmin : использовать Python как оболочку для выполнения команды оболочки

    • Win :

      (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
      
    • Nix ( Lnx ( Ubtu )):

      [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
      

Итог :

  • Использовать использовать попробовать / кроме <38 / 4215401538> <38 / 421538938> <38 / 4215389> наконец блоки, потому что они могут предотвратить появление ряда неприятных проблем. Противоположным примером, который я могу придумать, является производительность: такие блоки являются дорогостоящими, поэтому старайтесь не помещать их в код, который должен запускаться сотни тысяч раз в секунду (но поскольку (в большинстве случаев) это связано с доступом к диску, это не так).

Заключительные примечания :

  • Я постараюсь поддерживать его в актуальном состоянии, любые предложения приветствуются, я включу все полезное, что появится в ответе

sk8asd123
19 ноября 2017 в 01:46
3

Не могли бы вы уточнить это заявление? «Хотя это не очень хорошая практика, я использую в вызове os.F_OK, но это просто для ясности (его значение равно 0)»

CristiFati
19 ноября 2017 в 23:54
6

@ sk8asd123: Трудно обдумать это в комментарии: как правило, лучше использовать константы с функциями, с которыми они идут вместе. Это применимо при работе с несколькими модулями, которые определяют одну и ту же константу, потому что некоторые из них могут быть устаревшими, и лучше всего синхронизировать функции и константы. При работе с ctypes (вызывая функции напрямую) я должен был определить константу (из MSDN ) или вообще не использовать константу. Это просто рекомендация, которую я использую, в 99,9% случаев она, вероятно, не имеет значения (функционально).

ShadowRanger
29 ноября 2017 в 18:29
3

@CristiFati: Начиная с версии 3.6, glob.iglob (а также glob.glob) основаны на os.scandir, поэтому сейчас это лениво; чтобы получить первое попадание в каталог из 10 миллионов файлов, вы сканируете только до первого попадания. И даже до версии 3.6, если вы используете методы glob без каких-либо подстановочных знаков, функция умна: она знает, что у вас может быть только одно попадание, поэтому упрощает подстановку до os.path.isdir или os.path.lexists (в зависимости от того, заканчивается ли путь на /).

ShadowRanger
29 ноября 2017 в 18:38
3

Эта вторая часть моего комментария (подстановка без подстановочных знаков на самом деле не выполняет итерацию по папке и никогда не повторяет) означает, что это совершенно эффективное решение проблемы (медленнее, чем прямой вызов os.path.isdir или os.path.lexist, поскольку это куча Вызов функций уровня Python и строковые операции до того, как он решит, что эффективный путь жизнеспособен, но без дополнительных системных вызовов или операций ввода-вывода, что на порядки медленнее).

avatar
Taufiq Rahman
2 декабря 2016 в 06:39
14

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

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

avatar
Tom Fuller
8 октября 2016 в 12:43
90

Тестирование файлов и папок с os.path.isfile(), os.path.isdir() и os.path.exists()

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

enter image description here

Вы также можете проверить, является ли файл определенным типом файла, используя 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
avatar
Marcel Wilson
5 августа 2016 в 15:54
17

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

Это будет обрабатывать случай, когда 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):
Shahbaz
4 января 2017 в 22:50
3

if (x) return true; else return false; на самом деле просто return x. Ваши последние четыре строки могут стать return os.path.isfile(file_path). Пока мы это делаем, всю функцию можно упростить до return file_path and os.path.isfile(file_path).

Marcel Wilson
5 января 2017 в 17:08
0

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

Shahbaz
5 января 2017 в 17:10
1

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

Marcel Wilson
5 января 2017 в 17:13
0

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

Peter Wood
6 апреля 2017 в 10:35
3

return file_path and os.path.isfile(file_path)

avatar
iPhynx
8 июня 2016 в 12:45
6

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

import os
if 'file.ext' in os.listdir('dirpath'):
    #code
Jean-François Fabre
7 января 2017 в 12:24
3

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

avatar
Mike McKerns
5 мая 2016 в 12:00
17

Я являюсь автором пакета, который существует уже около 10 лет, и в нем есть функция, которая напрямую решает этот вопрос. Обычно, если вы работаете в системе, отличной от Windows, для доступа к find используется Popen. Однако, если вы работаете в 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

avatar
KaiBuxe
24 февраля 2016 в 12:44
76

В 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():
    ...
Joko
25 февраля 2016 в 08:55
4

Могу я спросить: в чем преимущество использования модуля pathlib вместо модуля os в python3 для этой проверки?

KaiBuxe
25 февраля 2016 в 10:44
4

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

avatar
Love and peace - Joe Codeswell
29 августа 2015 в 16:15
16

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

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

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

flotzilla
1 октября 2015 в 07:48
6

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

avatar
Aaron Hall
11 августа 2015 в 03:54
130

Как с помощью 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 диспетчера контекста.

Предотвращение состояний гонки без запроса 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

Другие варианты, которые не соответствуют запросу «без попытки»:

файл

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, за исключением того, чтобы избежать состояния гонки:

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

ос. Доступ

Для 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!) Проходить без уведомления, что является хорошим способом скрыть ошибки.

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

avatar
Khaled.K
5 августа 2015 в 06:28
10
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)
Khaled.K
9 августа 2015 в 07:46
0

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

avatar
loxsat
25 мая 2015 в 18:29
90
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.

Chris Johnson
1 августа 2015 в 13:56
10

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

avatar
Pedro Lobito
28 апреля 2015 в 02:45
21
if os.path.isfile(path_to_file):
    try: 
        open(path_to_file)
            pass
    except IOError as e:
        print "Unable to open file"

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

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

Chris Johnson
17 февраля 2016 в 18:58
3

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

avatar
Zizouz212
26 декабря 2014 в 20:05
53

Хотя я всегда рекомендую использовать операторы 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), чтобы вы могли, надеюсь, определить свою проблему. Я надеюсь, что это помогает! :)

avatar
Pradip Das
20 декабря 2014 в 15:21
14

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

>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt") 
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False
Chris Johnson
1 августа 2015 в 13:55
5

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

Pradip Das
2 августа 2015 в 14:51
0

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

Debosmit Ray
14 апреля 2016 в 23:33
0

Итак, этот ответ работает. Здорово. Iff путь не путь к файлу. Это то, о чем был вопрос? Нет.

starturtle
5 сентября 2017 в 11:24
0

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

avatar
Hanson
17 октября 2014 в 21:25
7

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

from sys import argv

from os.path import exists
script, filename = argv
target = open(filename)
print "file exists: %r" % exists(filename)
Pavel Chernikov
23 августа 2015 в 02:12
6

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

avatar
bergercookie
13 октября 2014 в 07:45
40

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

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

ОБНОВЛЕНИЕ

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

Chris Johnson
1 августа 2015 в 13:55
9

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

Zorglub29
19 мая 2018 в 21:33
0

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

JayRizzo
31 августа 2018 в 23:24
0

docs.python.org/3/library/os.path.html#os.path.exists К приведенному выше утверждению от chris >> os.path.exists (путь)> Верните True, если путь относится к существующему пути или дескриптору открытого файла. Возвращает False для неработающих символических ссылок. На некоторых платформах эта функция может возвращать False, если не предоставлено разрешение на выполнение os.stat () для запрошенного файла, даже если путь физически существует. Изменено в версии 3.3: теперь путь может быть целым числом: True возвращается, если это дескриптор открытого файла, в противном случае - False. Изменено в версии 3.6: принимает объект, подобный пути.

avatar
aitchnyu
18 сентября 2014 в 04:39
7
import os
path = /path/to/dir

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

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

Chris Johnson
13 июня 2017 в 22:10
3

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

avatar
Zaheer
23 мая 2014 в 10:01
8

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

file = open(inputFile, 'r')
file.close()
Sam Dolan
19 февраля 2020 в 22:06
5

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

avatar
Chris
10 февраля 2014 в 21:30
19

Вы можете написать предложение Брайана без 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
avatar
Cody Piersall
8 февраля 2014 в 02:38
197

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
Ryan Haining
11 октября 2020 в 21:13
0

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

avatar
chad
25 сентября 2013 в 01:52
69

Не похоже, что есть значимая функциональная разница между 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'

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

Chris Johnson
1 августа 2015 в 13:54
4

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

spectras
24 августа 2015 в 14:05
6

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

Tom Myddeltyn
24 мая 2016 в 14:14
1

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

ShadowRanger
29 ноября 2017 в 18:14
0

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

ShadowRanger
29 ноября 2017 в 18:17
0

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

avatar
un33k
27 июня 2013 в 13:38
159

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

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 ноября 2014 в 18:37
17

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

un33k
28 июля 2018 в 02:52
0

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

avatar
user2154354
4 апреля 2013 в 18:21
8

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

from os.path import exists

if exists("file") == True:
    print "File exists."
elif exists("file") == False:
    print "File doesn't exist."
Dmitry
27 апреля 2013 в 13:21
1

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

tripleee
22 августа 2013 в 06:45
23

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

Chris Johnson
3 августа 2015 в 15:10
13

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

avatar
Yugal Jindle
16 января 2012 в 05:57
390

Используйте 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
9 апреля 2013 в 05:45
66

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

user207421
13 марта 2018 в 00:01
14

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

e-info128
16 июля 2018 в 21:30
9

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

Jester
24 августа 2018 в 13:10
9

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

Martin Meeser
2 июля 2020 в 07:04
1

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

avatar
philberndt
25 января 2011 в 23:00
62

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

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] Нет такого файла или каталога: 'something.txt')

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

rrs
23 апреля 2014 в 13:10
20

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

Chris Johnson
17 февраля 2016 в 18:52
6

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

avatar
pkoch
4 ноября 2009 в 00:48
131

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

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

BlueTrin
10 сентября 2015 в 09:09
3

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

jstine
28 сентября 2015 в 15:38
11

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

Camion
24 мая 2019 в 10:43
0

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

avatar
bortzmeyer
17 сентября 2008 в 15:01
1077

В отличие от 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
avatar
zgoda
17 сентября 2008 в 13:13
40

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

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

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

avatar
rslite
17 сентября 2008 в 12:57
5746

Если причина, по которой вы проверяете, заключается в том, чтобы вы могли сделать что-то вроде 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
makapuf
20 июня 2018 в 07:58
59

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

scottclowe
29 марта 2019 в 13:44
12

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

kyrill
30 апреля 2019 в 17:45
13

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

theX
2 июля 2020 в 21:26
0

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

hagello
20 ноября 2020 в 14:48
1

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

avatar
PierreBdR
17 сентября 2008 в 12:57
2339

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

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

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

os.path.isfile(file_path)

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

avatar
benefactual
17 сентября 2008 в 12:56
323
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
3 апреля 2020 в 17:10
5

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

avatar
Paul
17 сентября 2008 в 12:55
745
import os.path

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