Как проверить, существует ли файл?

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

4311
задан spence91 17 сент. '08 в 15:55
источник поделиться
45 ответов
  • 1
  • 2

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

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

Вернуть True если путь - это существующий обычный файл. Это следует за символическими ссылками, поэтому оба islink() и isfile() могут быть истинными для одного и того же пути.

import os.path
os.path.isfile(fname) 

если вам нужно убедиться, что это файл.

Начиная с Python 3.4, модуль pathlib предлагает объектно-ориентированный подход (backported to 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() в блоке try:

try:
    my_abs_path = my_file.resolve()
except FileNotFoundError:
    # doesn't exist
else:
    # exists
3916
ответ дан rslite 17 сент. '08 в 15:57
источник поделиться

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

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

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

os.path.isfile(file_name)

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

1612
ответ дан PierreBdR 17 сент. '08 в 15:57
источник поделиться

В отличие от isfile(), exists() будет return True для каталогов.
Поэтому в зависимости от того, хотите ли вы использовать только обычные файлы или каталоги, вы будете использовать isfile() или exists(). Вот простой вывод REPL.

>>> print os.path.isfile("/etc/password.txt")
True
>>> print os.path.isfile("/etc")
False
>>> print os.path.isfile("/does/not/exist")
False
>>> print os.path.exists("/etc/password.txt")
True
>>> print os.path.exists("/etc")
True
>>> print os.path.exists("/does/not/exist")
False
832
ответ дан bortzmeyer 17 сент. '08 в 18:01
источник поделиться
import os.path

if os.path.isfile(filepath):
463
ответ дан Paul 17 сент. '08 в 15:55
источник поделиться

Используйте os.path.isfile() с os.access():

import os
import os.path

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"
214
ответ дан Yugal Jindle 16 янв. '12 в 8:57
источник поделиться
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
204
ответ дан benefactual 17 сент. '08 в 15:56
источник поделиться

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

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")
137
ответ дан un33k 27 июня '13 в 16:38
источник поделиться

2017/12/22:

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

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

Заявление о проблемах:

  1. Проверить файл (возможно: также папка ("специальный" файл)?) Существование
  2. Не используйте блоки try/except/else/finally

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

  1. [Python]: os.path. существует (путь) (также проверяйте другие члены семейства функций, такие как os.path.isfile, os.path.isdir, os.path.lexists для немного другого поведения)

    os.path.exists(path)
    

    Вернуть True если путь относится к существующему пути или описателю открытого файла. Возвращает False для сломанных символических ссылок. На некоторых платформах эта функция может возвращать False если разрешение не предоставлено для выполнения os.stat() в запрошенном файле, даже если путь физически существует.

    Все хорошо, но если следовать дереву импорта:

    • os.path - posixpath.py(ntpath.py)

      • genericpath.py, строка ~ # 20+

        def exists(path):
            """Test whether a path exists.  Returns False for broken symbolic links"""
            try:
                st = os.stat(path)
            except os.error:
                return False
            return True
        

    это просто блок try/except вокруг [Python]: os. stat (путь, *, dir_fd = None, follow_symlinks = True). Таким образом, ваш код try/except free, но ниже в рамке там (по крайней мере) один такой блок. Это также относится к другим функциям (включая os.path.isfile).

    1.1. [Python]: pathlib.Path. is_file()

    • Это любительский (и более питонический) способ обработки путей, но
    • Под капотом, он делает то же самое (pathlib.py, линия ~ # 1330):

      def is_file(self):
          """
          Whether this path is a regular file (also True for symlinks pointing
          to regular files).
          """
          try:
              return S_ISREG(self.stat().st_mode)
          except OSError as e:
              if e.errno not in (ENOENT, ENOTDIR):
                  raise
              # Path doesn't exist or is a broken symlink
              # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
              return False
      
  2. [Python]: с менеджерами контекста Statement. Или:

    • Создай:

      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 ...)
      
      • И его использование - я буду реплицировать поведение 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]: contextlib. подавляющие (* исключения) - который был специально предназначен для выборочного подавляющих исключений


    Но они кажутся обертками поверх try/except/else/finally блоков, как [Python]: оператор with утверждает:

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

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


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

  4. [Python]: os. access (путь, режим, *, dir_fd = None, effective_ids = False, follow_symlinks = True), поведение которого близко к os.path.exists (на самом деле оно шире, главным образом из-за 2- го аргумента)

    • пользовательские разрешения могут ограничивать файл "видимость", поскольку состояние документа:

      ... проверить, имеет ли вызывающий пользователь указанный путь к пути. режим должен быть F_OK для проверки существования пути...

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

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

    Примечание: вызов native API также возможен через [Python]: ctypes - библиотека внешних функций для Python, но в большинстве случаев это сложнее.

    (Win specific): Поскольку msvcr * (vcruntime *) экспортирует семейство функций [MSDN]: _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", 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"/tmp1", os.F_OK)
    -1
    

    Примечания:

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

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

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

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

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

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

    • Выиграть:

      (py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe\" > nul 2>&1'))"
      0
      
      (py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe.notexist\" > nul 2>&1'))"
      1
      
    • Lnx (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
      

Итог:

  • Используют ли try/за except/else/finally блоков, потому что они могут помешать вам запуск в серию неприятных проблем. Контр-пример, который я могу придумать, - это производительность: такие блоки являются дорогостоящими, поэтому постарайтесь не размещать их в коде, который он должен запускать сотни тысяч раз в секунду (но поскольку (в большинстве случаев) он включает в себя доступ к диску, это не так).

Заключительное примечание (и):

  • Я постараюсь держать его в курсе, любые предложения приветствуются, я включу что-нибудь полезное, которое придет в ответ
133
ответ дан CristiFati 20 июня '17 в 22:28
источник поделиться

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
120
ответ дан Cody Piersall 08 февр. '14 в 5:38
источник поделиться

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

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

110
ответ дан pkoch 04 нояб. '09 в 3:48
источник поделиться

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

Здесь help на 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 вы просто пытаетесь прочитать свой файл, ожидая, что он будет там, а если нет, вы поймаете исключение и выполните все возможные действия резервного копирования.

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

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

Но если это ваша мотивация, вы можете получить значение инструкции 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)

из docs:

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

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. Из docs:

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

Это, по-видимому, побуждает пользователей принимать плохие практики.

99
ответ дан Aaron Hall 11 авг. '15 в 6: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.

76
ответ дан Bishop 25 мая '15 в 21:29
источник поделиться

Тестирование файлов и папок с помощью 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
64
ответ дан Tom Fuller 08 окт. '16 в 15:43
источник поделиться

В 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():
    ...
58
ответ дан KaiBuxe 24 февр. '16 в 15:44
источник поделиться

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

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

58
ответ дан chad 25 сент. '13 в 4:52
источник поделиться

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

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

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

49
ответ дан philberndt 26 янв. '11 в 2:00
источник поделиться

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

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

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

    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
    
  • Используйте os.path.exists(path):

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

    import os.path
    >>> os.path.exists("this/is/a/directory")
    True
    >>> os.path.exists("this/is/a/file.txt")
    True
    >>> os.path.exists("not/a/directory")
    False
    
  • Используйте os.access(path, mode):

    Это проверит, есть ли у вас доступ к файлу. Он будет проверять разрешения. На основе документации os.py, набрав os.F_OK, он проверяет существование пути. Тем не менее, использование этого приведет к созданию дыры в безопасности, так как кто-то может атаковать ваш файл, используя время между проверкой разрешений и открытием файла. Вместо этого вы должны перейти непосредственно к открытию файла, а не проверять его разрешения. (EAFP vs 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), чтобы вы могли, надеюсь, определить вашу проблему. Я надеюсь, что это помогает!:)

43
ответ дан Zizouz212 26 дек. '14 в 23:05
источник поделиться

Кроме того, os.access():

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

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

31
ответ дан zgoda 17 сент. '08 в 16:13
источник поделиться

В Python 3.4 язык предоставляет новый модуль для управления файлами:

import pathlib
path = pathlib.Path('path/to/file')
if path.is_file(): # If you want to check a directory: path.is_dir()
    # If it is true, return true on your code.
31
ответ дан Unai Sainz de la Maza 06 нояб. '15 в 0:15
источник поделиться

Просто чтобы добавить к путанице, кажется, что предложенный ранее метод try: open() не работает в Python, поскольку доступ к файлам не является исключительным, даже при записи в файлы, c.f. Каков наилучший способ открыть файл для эксклюзивного доступа в Python?.

19
ответ дан Tilman 22 нояб. '10 в 19:19
источник поделиться
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

19
ответ дан Pedro Lobito 28 апр. '15 в 5:45
источник поделиться

Вы можете написать предложение Брайана без 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
16
ответ дан Chris 11 февр. '14 в 0:30
источник поделиться

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

Это будет обрабатывать случай 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
ответ дан Marcel Wilson 05 авг. '16 в 18:54
источник поделиться

Здесь приведена 1 строка команды Python для среды командной строки Linux. Я нахожу это ОЧЕНЬ HANDY, так как я не такой горячий парень Bash.

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

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

15
ответ дан Love and peace - Joe Codeswell 29 авг. '15 в 19:15
источник поделиться

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

В самом коде не используется блок try... кроме определения операционной системы и, таким образом, управление вами в стиле "Unix" find или ручном built 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

14
ответ дан Mike McKerns 05 мая '16 в 15:00
источник поделиться

Проверить файл или каталог

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

Примечание1: os.path.isfile используется только для файлов

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

Примечание2: os.path.exists используется как для файлов, так и для каталогов

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

Метод pathlib.Path (включен в Python 3+, устанавливается с помощью пипа для Python 2)

from pathlib import Path
Path(filename).exists()
12
ответ дан Ali Hallaji 04 марта '18 в 9:24
источник поделиться

Дата: 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']}
11
ответ дан JawSaw 04 дек. '17 в 11:51
источник поделиться

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

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

11
ответ дан Inconnu 02 дек. '16 в 9:39
источник поделиться

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

>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt") 
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False
11
ответ дан Pradip Das 20 дек. '14 в 18:21
источник поделиться
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)
10
ответ дан Khaled.K 05 авг. '15 в 9:28
источник поделиться
  • 1
  • 2

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