it-swarm-ru.tech

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

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

5051
spence91

Если причина, по которой вы проверяете, заключается в том, что вы можете сделать что-то вроде 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
4627
rslite

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

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

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

os.path.isfile(file_path)

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

1930
PierreBdR

В отличие от isfile() , exists() вернет 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
892
bortzmeyer
import os.path

if os.path.isfile(filepath):
551
Paul

Используйте 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"
270
Yugal Jindle
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
253
benefactual

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

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

Постановка задачи :

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

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

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

    os.path.exists(path)
    

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

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

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

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

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

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

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

    • Это более интересный (и более python ic) способ обработки путей, но
    • Под капотом он делает точно то же самое ( pathlib.py , line ~ # 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. suppress ( * exception ) - который был специально предназначен для выборочного подавления исключений


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

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

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


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

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

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

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

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

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

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

    ( Win специально): так как vcruntime * ( msvcr * ) . dll экспортирует [MS.Docs]: _access, _waccess семейство функций а вот пример:

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

    Примечания :

    • Хотя это не очень хорошая практика, я использую os.F_OK в вызове, но это только для ясности (его значение 0 )
    • Я использую _ 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" ), который может (и, скорее всего, будет) различаться в разных системах, None (или пустая строка) может быть передано конструктору CDLL (ctypes.CDLL(None).access(b"/tmp", os.F_OK)). Согласно [man7]: DLOPEN (3) :

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

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

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

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

  6. Другой (неудачный) обходной путь ( gainarie ) - это (как мне нравится это называть) подход sysadmin : use 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 )):

      [[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp\" > /dev/null 2>&1'))"
      0
      [[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp.notexist\" > /dev/null 2>&1'))"
      512
      

Нижняя строка :

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

Последнее примечание (я) :

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

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

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

В 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
133
Cody Piersall

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

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

117
pkoch

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

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

Поэтому нам нужно использовать is_file:

>>> root.is_file()
False

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

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

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

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

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

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

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

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

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

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

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

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

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

Как избежать условий гонки без указания try: suppress

Python 3.4 предоставляет нам менеджер контекста suppress (ранее - менеджер контекста ignore ), который выполняет семантически точно то же самое в меньшем количестве строк, а также (по крайней мере, поверхностно) встречает оригинал, чтобы избежать try заявления:

from contextlib import suppress
from pathlib import Path

Использование:

>>> with suppress(OSError), Path('doesnotexist').open() as f:
...     for line in f:
...         print(line)
... 
>>>
>>> with suppress(OSError):
...     Path('doesnotexist').unlink()
... 
>>> 

Для более ранних Pythons вы можете бросить свой собственный suppress, но без try будет более многословно, чем с. Я верю , что на самом деле это единственный ответ, который не использует try на любом уровне Python , который может быть применен до Python 3.4, потому что вместо него используется менеджер контекста:

class suppress(object):
    def __init__(self, *exceptions):
        self.exceptions = exceptions
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is not None:
            return issubclass(exc_type, self.exceptions)

Возможно, проще с попыткой:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass

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

ISFILE

import os
os.path.isfile(path)

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

os.path.isfile(path)

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

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

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

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

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

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

os.access

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

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

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

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

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

лучше написано как:

try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCES:
        return "some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()

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

Критика другого ответа:

Другой ответ говорит об этом os.access:

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

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

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

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

110
Aaron Hall
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.

82
bishop

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

В 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():
    ...
67
KaiBuxe

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

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

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

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

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

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

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

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

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

62
chad

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

try:
    # http://effbot.org/zone/python-with-statement.htm
    # 'with' is safer to open a file
    with open('whatever.txt') as fh:
        # Do something with 'fh'
except IOError as e:
    print("({})".format(e))

Результат будет:

([Errno 2] Нет такого файла или каталога: 'what.txt')

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

53
philberndt

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

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

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

    def File_Existence(filepath):
        f = open(filepath)
        return True
    

    Если это значение False, оно прекратит выполнение с неуправляемым IOError или OSError в более поздних версиях Python. Чтобы поймать исключение, вы должны использовать предложение try, кроме. Конечно, вы всегда можете использовать оператор try кроме`, например, так (спасибо hsandt за то, что заставил меня задуматься):

    def File_Existence(filepath):
        try:
            f = open(filepath)
        except IOError, OSError: # Note OSError is for later versions of Python
            return False
    
        return True
    
  2. Используйте os.path.exists(path):

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

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

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

48
Zizouz212

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

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

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

Будучи R_OK, W_OK и X_OK флагами для проверки прав доступа ( doc ).

33
zgoda

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

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

UPDATE

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

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

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

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

20
Pedro Lobito

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

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

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

18
durjoy

Вы можете написать предложение Брайана без try:.

from contextlib import suppress

with suppress(IOError), open('filename'):
    process()

suppress является частью Python 3.4. В старых версиях вы можете быстро написать свой собственный подавитель:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass
17
Chris

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

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

Примечание 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()
16
Ali Hallaji

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

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

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

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

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

И док ...

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

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

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

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

>>>

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

15
Mike McKerns

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

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

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

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) ошибок.

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

11
Inconnu

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

def isReadableFile(file_path, file_name):
    full_path = file_path + "/" + file_name
    try:
        if not os.path.exists(file_path):
            print "File path is invalid."
            return False
        Elif not os.path.isfile(full_path):
            print "File does not exist."
            return False
        Elif not os.access(full_path, os.R_OK):
            print "File cannot be read."
            return False
        else:
            print "File can be read."
            return True
    except IOError as ex:
        print "I/O error({0}): {1}".format(ex.errno, ex.strerror)
    except Error as ex:
        print "Error({0}): {1}".format(ex.errno, ex.strerror)
    return False
#------------------------------------------------------

path = "/usr/khaled/documents/puzzles"
fileName = "puzzle_1.txt"

isReadableFile(path, fileName)
9
Khaled.K

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

open(inputFile, 'r')
9
user3197473
import os
path = /path/to/dir

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

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

7
Jesvin Jose

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

from sys import argv

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

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

import os
if 'file.ext' in os.listdir('dirpath'):
    #code
4
iPhynx
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.

3
Vimal Maheedharan

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

from os.path import exists

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

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

import os

def file_exists(path, filename):
    for file_or_folder in os.listdir(path):
        if file_or_folder == filename:
            return True
    return False
0
The dark side of Gaming