Respostas:
Se o motivo que você está verificando é para que você possa fazer algo assim if file_exists: open_it()
, é mais seguro usar uma try
tentativa de abri-lo. Verificar e abrir o risco de o arquivo ser excluído ou movido ou algo entre quando você verifica e quando tenta abri-lo.
Se você não planeja abrir o arquivo imediatamente, pode usar os.path.isfile
Retorne
True
se path for um arquivo regular existente. Isso segue links simbólicos, portanto, islink () e isfile () podem ser verdadeiros para o mesmo caminho.
import os.path
os.path.isfile(fname)
se você precisa ter certeza de que é um arquivo.
A partir do Python 3.4, o pathlib
módulo oferece uma abordagem orientada a objetos (suportada pathlib2
no Python 2.7):
from pathlib import Path
my_file = Path("/path/to/file")
if my_file.is_file():
# file exists
Para verificar um diretório, faça:
if my_file.is_dir():
# directory exists
Para verificar se um Path
objeto existe independentemente de ser um arquivo ou diretório, use exists()
:
if my_file.exists():
# path exists
Você também pode usar resolve(strict=True)
em um try
bloco:
try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
FileNotFoundError
foi introduzido no Python 3. Se você também precisa apoiar Python 2.7, bem como Python 3, você pode usar IOError
em vez (que FileNotFoundError
subclasses) stackoverflow.com/a/21368457/1960959
open('file', 'r+')
) e depois procurar o final.
Você tem a os.path.exists
função:
import os.path
os.path.exists(file_path)
Isso retorna True
para arquivos e diretórios, mas você pode usar
os.path.isfile(file_path)
para testar se é um arquivo especificamente. Segue links simbólicos.
Ao contrário isfile()
, exists()
retornará True
para diretórios. Portanto, dependendo se você deseja apenas arquivos simples ou também diretórios, você usará isfile()
ou exists()
. Aqui está uma saída REPL simples:
>>> 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
Use os.path.isfile()
com 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")
os.access()
retornará false.
import os
você não precisa import os.path
novamente, pois já faz parte os
. Você só precisa importar os.path
se deseja usar funções de os.path
e não de os
si mesmo, para importar algo menor, mas à medida que você usa os.access
e os.R_OK
, a segunda importação não é necessária.
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
Embora quase todas as formas possíveis tenham sido listadas em (pelo menos uma das) respostas existentes (por exemplo, coisas específicas do Python 3.4 foram adicionadas), tentarei agrupar tudo.
Nota : cada parte do código da biblioteca padrão do Python que vou postar pertence à versão 3.5.3 .
Declaração do problema :
Possíveis soluções :
[Python 3]: os.path. existe ( caminho ) (verifique também outros membros da família como função os.path.isfile
, os.path.isdir
, os.path.lexists
para comportamentos ligeiramente diferentes)
os.path.exists(path)
Retorne
True
se path se referir a um caminho existente ou a um descritor de arquivo aberto. RetornaFalse
para links simbólicos quebrados. Em algumas plataformas, essa função pode retornarFalse
se a permissão não for concedida para executar os.stat () no arquivo solicitado, mesmo que o caminho exista fisicamente.
Tudo bem, mas se seguir a árvore de importação:
os.path
- posixpath.py ( ntpath.py )
genericpath.py , linha ~ # 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
é apenas um bloco try / except em torno de [Python 3]: os. stat ( caminho, *, dir_fd = Nenhum, follow_symlinks = True ) . Portanto, seu código é try / except free, mas mais baixo no framestack existe (pelo menos) um desses blocos. Isso também se aplica a outras funções ( inclusive os.path.isfile
).
1.1 [Python 3]: caminho. is_file ()
Sob o capô, ele faz exatamente a mesma coisa ( pathlib.py , linha ~ # 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
[Python 3]: com gerenciadores de contexto de instrução . Ou:
Crie um:
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 ...)
E seu uso - replicarei o os.path.isfile
comportamento (observe que isso é apenas para fins de demonstração, não tente escrever esse código para produção ):
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
Use [Python 3]: contextlib. suprimir ( * exceções ) - que foi projetado especificamente para suprimir seletivamente exceções
Mas, eles parecem ser wrappers sobre blocos try / except / else / finalmente , como [Python 3]: A declaração with afirma:
Isso permite que tentativas comuns ... exceto ... finalmente , padrões de uso sejam encapsulados para reutilização conveniente.
Funções transversais do sistema de arquivos (e pesquise os resultados pelos itens correspondentes)
[Python 3]: os. listdir ( caminho = '.' ) (ou [Python 3]: os. scandir ( caminho = '.' ) no Python v 3.5 +, backport: [PyPI]: scandir )
Sob o capô, ambos usam:
via [GitHub]: python / cpython - (mestre) cpython / Módulos / posixmodule.c
Usar scandir () em vez de listdir () pode aumentar significativamente o desempenho do código que também precisa de informações sobre o tipo ou o atributo do arquivo, porque os objetos os.DirEntry expõem essas informações se o sistema operacional as fornecer ao varrer um diretório. Todos os métodos os.DirEntry podem executar uma chamada do sistema, mas is_dir () e is_file () geralmente requerem apenas uma chamada do sistema para links simbólicos; os.DirEntry.stat () sempre requer uma chamada do sistema no Unix, mas apenas uma para links simbólicos no Windows.
os.listdir
( os.scandir
quando disponível)glob.glob
)
os.listdir
Como essas iterações nas pastas (na maioria dos casos) são ineficientes para o nosso problema (há exceções, como glob bing sem caracteres curinga - como o @ShadowRanger apontou), então não vou insistir nelas. Sem mencionar que, em alguns casos, o processamento do nome do arquivo pode ser necessário.
[Python 3]: os. de acesso ( de caminho, modo, *, dir_fd = None, effective_ids = false, follow_symlinks = true ) cujo comportamento está perto os.path.exists
(na verdade, é mais amplo, principalmente por causa da 2 nd argumento)
... teste se o usuário que está chamando tem o acesso especificado ao caminho . O modo deve ser F_OK para testar a existência do caminho ...
os.access("/tmp", os.F_OK)
Desde que eu também trabalho em C , eu uso este método, mas também porque sob o capô, ele chama nativa API s (mais uma vez, através de "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c" ), mas também abre uma porta para um possível usuário erros e não é tão Python ic quanto outras variantes. Portanto, como o @AaronHall apontou corretamente, não o use, a menos que você saiba o que está fazendo:
Nota : chamar APIs nativas também é possível via [Python 3]: ctypes - Uma biblioteca de funções estrangeira para Python , mas na maioria dos casos é mais complicado.
( Específico para Windows ): Como o vcruntime * ( msvcr * ) .dll exporta uma família de funções [MS.Docs]: _access, _waccess , aqui está um exemplo:
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
Notas :
os.F_OK
a chamada, mas isso é apenas para esclarecer (seu valor é 0 )
A contraparte do Lnx ( Ubtu (16 x64) ) também:
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
Notas :
Em vez disso, codifique o caminho da libc ( "/lib/x86_64-linux-gnu/libc.so.6" ) que pode (e provavelmente irá) variar entre os sistemas. Nenhum (ou a string vazia) pode ser passado ao construtor CDLL ( ctypes.CDLL(None).access(b"/tmp", os.F_OK)
) De acordo com [man7]: DLOPEN (3) :
Se o nome do arquivo for NULL, o identificador retornado será para o programa principal. Quando atribuído a dlsym (), esse identificador causa uma pesquisa por um símbolo no programa principal, seguido por todos os objetos compartilhados carregados na inicialização do programa e, em seguida, todos os objetos compartilhados carregados por dlopen () com o sinalizador RTLD_GLOBAL .
__declspec(dllexport)
(por que diabos a pessoa comum faria isso?), o programa principal é carregável, mas praticamente inutilizávelInstale algum módulo de terceiros com recursos do sistema de arquivos
Provavelmente, contará com uma das maneiras acima (talvez com pequenas personalizações).
Um exemplo seria (novamente, específico para Win ) [GitHub]: mhammond / pywin32 - Extensões do Python para Windows (pywin32) , que é um wrapper do Python sobre o WINAPI s.
Mas, como isso é mais uma solução alternativa, estou parando aqui.
Outra solução alternativa (lame) ( gainarie ) é (como eu gosto de chamar), a abordagem sysadmin : use Python como um wrapper para executar comandos de shell
Vitória :
(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
Bottom line :
Nota (s) final (is) :
glob.iglob
(e glob.glob
também) são baseadosos.scandir
, por isso é preguiçoso agora; para obter o primeiro hit em um diretório com 10 milhões de arquivos, você só escaneia até chegar ao primeiro hit. E mesmo antes da 3.6, se você usar glob
métodos sem curingas, a função é inteligente: ela sabe que você pode ter apenas um hit, simplificando o globbing para apenas os.path.isdir
ouos.path.lexists
(dependendo se o caminho termina /
).
os.path.isdir
ou os.path.lexist
uma vez que é um monte de chamadas e seqüências de funções no nível Python operações antes de decidir que o caminho eficiente é viável, mas nenhuma chamada adicional do sistema ou trabalho de E / S, que é de magnitude mais lenta).
Essa é a maneira mais simples de verificar se existe um arquivo. Só porque o arquivo existia quando você verificou não garante que ele estará lá quando você precisar abri-lo.
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")
O Python 3.4+ possui um módulo de caminho orientado a objetos: pathlib . Usando este novo módulo, você pode verificar se existe um arquivo como este:
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
Você pode (e geralmente deve) ainda usar um try/except
bloco ao abrir arquivos:
try:
with p.open() as f:
# do awesome stuff
except OSError:
print('Well darn.')
O módulo pathlib possui muitas coisas interessantes: globbing conveniente, verificação do proprietário do arquivo, junção de caminho mais fácil etc. Vale a pena conferir. Se você estiver em um Python mais antigo (versão 2.6 ou posterior), ainda poderá instalar o pathlib com o pip:
# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2
Importe-o da seguinte maneira:
# Older Python versions
import pathlib2 as pathlib
Prefira a instrução try. É considerado um estilo melhor e evita condições de corrida.
Não aceite minha palavra. Há bastante apoio para essa teoria. Aqui estão alguns:
try...except
não ajuda a resolver esse problema de qualquer maneira.
except:
cláusula fará com que uma exceção resultante dessa parte do código gere uma mensagem confusa (segundo erro gerado durante o processamento do primeiro.)
Como verifico se existe um arquivo, usando Python, sem usar uma instrução try?
Agora disponível desde o Python 3.4, importe e instancie um Path
objeto com o nome do arquivo e verifique o is_file
método (observe que isso retorna True para links simbólicos que também apontam para arquivos regulares):
>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False
Se você estiver no Python 2, poderá fazer o backport do módulo pathlib a partir do pypi pathlib2
, ou verificar isfile
no os.path
módulo:
>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False
Agora, a descrição acima é provavelmente a melhor resposta direta pragmática aqui, mas há a possibilidade de uma condição de corrida (dependendo do que você está tentando realizar) e o fato de a implementação subjacente usar a try
, mas o Python usa try
em toda parte em sua implementação.
Como o Python usa em try
qualquer lugar, não há realmente nenhuma razão para evitar uma implementação que o utilize.
Mas o restante desta resposta tenta considerar essas advertências.
Disponível desde o Python 3.4, use o novo Path
objeto em pathlib
. Note que isso .exists
não está certo, porque diretórios não são arquivos (exceto no sentido unix de que tudo é um arquivo).
>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True
Então, precisamos usar is_file
:
>>> root.is_file()
False
Aqui está a ajuda sobre is_file
:
is_file(self)
Whether this path is a regular file (also True for symlinks pointing
to regular files).
Então, vamos pegar um arquivo que sabemos que é um arquivo:
>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True
Por padrão, NamedTemporaryFile
exclui o arquivo quando fechado (e será fechado automaticamente quando não houver mais referências a ele).
>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False
Se você se aprofundar na implementação , verá que is_file
usa 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
Gostamos try
porque evita as condições da corrida. Com try
, você simplesmente tenta ler seu arquivo, esperando que ele esteja lá; caso contrário, captura a exceção e executa qualquer comportamento de fallback que faça sentido.
Se você deseja verificar a existência de um arquivo antes de tentar lê-lo e pode estar excluindo-o e estar usando vários threads ou processos, ou outro programa conhece esse arquivo e pode excluí-lo - você corre o risco de uma condição de corrida, se você verificar que ela existe, porque você está correndo para abri-la antes que sua condição (sua existência) mude.
As condições de corrida são muito difíceis de depurar porque há uma janela muito pequena na qual elas podem causar falha no seu programa.
Mas se essa é sua motivação, você pode obter o valor de uma try
declaração usando o suppress
gerenciador de contexto.
suppress
O Python 3.4 nos fornece o suppress
gerenciador de contexto (anteriormente o ignore
gerenciador de contexto), que semanticamente faz exatamente a mesma coisa em menos linhas, enquanto também (pelo menos superficialmente) atende à solicitação original para evitar uma try
declaração:
from contextlib import suppress
from pathlib import Path
Uso:
>>> with suppress(OSError), Path('doesnotexist').open() as f:
... for line in f:
... print(line)
...
>>>
>>> with suppress(OSError):
... Path('doesnotexist').unlink()
...
>>>
Para Pythons anteriores, você poderia fazer o seu próprio suppress
, mas sem um try
será mais detalhado do que com. Eu acredito que essa é realmente a única resposta que não usa try
em nenhum nível no Python que possa ser aplicada antes do Python 3.4, porque ele usa um gerenciador de contexto:
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)
Talvez mais fácil com uma tentativa:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
isfile
import os
os.path.isfile(path)
dos documentos :
os.path.isfile(path)
Retorne True se path for um arquivo regular existente. Isso segue links simbólicos, portanto, ambos
islink()
eisfile()
podem ser verdadeiros para o mesmo caminho.
Mas se você examinar a fonte dessa função, verá que ela realmente usa uma instrução 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
Tudo o que está fazendo é usar o caminho fornecido para ver se ele pode obter estatísticas, capturar OSError
e verificar se é um arquivo, se não gerou a exceção.
Se você pretende fazer algo com o arquivo, sugiro que tente diretamente com uma tentativa, exceto para evitar uma condição de corrida:
try:
with open(path) as f:
f.read()
except OSError:
pass
os.access
Disponível para Unix e Windows os.access
, é necessário , mas para usá-lo, você deve passar sinalizadores, e não diferencia entre arquivos e diretórios. Isso é mais usado para testar se o usuário que está chamando real tem acesso em um ambiente de privilégios elevados:
import os
os.access(path, os.F_OK)
Também sofre dos mesmos problemas de condição de corrida que isfile
. Dos documentos :
Nota: O uso de access () para verificar se um usuário está autorizado a, por exemplo, abrir um arquivo antes de fazê-lo usando open () cria uma falha de segurança, porque o usuário pode explorar o curto intervalo de tempo entre verificar e abrir o arquivo para manipulá-lo. É preferível usar técnicas de EAFP. Por exemplo:
if os.access("myfile", os.R_OK): with open("myfile") as fp: return fp.read() return "some default data"
é melhor escrito como:
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()
Evite usar os.access
. É uma função de baixo nível que tem mais oportunidades de erro do usuário do que os objetos e funções de nível superior discutidos acima.
Outra resposta diz o seguinte os.access
:
Pessoalmente, prefiro este porque, sob o capô, ele chama APIs nativas (via "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c"), mas também abre uma porta para possíveis erros do usuário, e não é tão Pythonic quanto outras variantes :
Esta resposta diz que prefere um método não pitonico e propenso a erros, sem justificativa. Parece incentivar os usuários a usar APIs de baixo nível sem entendê-las.
Ele também cria um gerenciador de contexto que, ao retornar incondicionalmente True
, permite todas as exceções (incluindo KeyboardInterrupt
eSystemExit
!) Passem silenciosamente, o que é uma boa maneira de ocultar bugs.
Isso parece incentivar os usuários a adotar práticas inadequadas.
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!"
A importação os
facilita a navegação e a execução de ações padrão com o sistema operacional.
Para referência, consulte Como verificar se existe um arquivo usando Python?
Se você precisar de operações de alto nível, use shutil
.
os.path.exists
retorna true para itens que não são arquivos, como diretórios. Isso dá falsos positivos. Veja as outras respostas recomendadas os.path.isfile
.
Teste para arquivos e pastas com os.path.isfile()
, os.path.isdir()
eos.path.exists()
Supondo que o "caminho" seja um caminho válido, esta tabela mostra o que é retornado por cada função para arquivos e pastas:
Você também pode testar se um arquivo é um determinado tipo de arquivo usado os.path.splitext()
para obter a extensão (se você ainda não o conhece)
>>> 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
Em 2016, a melhor maneira ainda está usando os.path.isfile
:
>>> os.path.isfile('/path/to/some/file.txt')
Ou no Python 3 você pode usar pathlib
:
import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
...
pathlib
é a solução OOP do python para caminhos. Você pode fazer muito mais com isso. Se você só precisa verificar a existência, a vantagem não é tão grande.
Não parece haver uma diferença funcional significativa entre try / except e isfile()
, portanto, você deve usar qual deles faz sentido.
Se você quiser ler um arquivo, se existir, faça
try:
f = open(filepath)
except IOError:
print 'Oh dear.'
Mas se você quiser renomear um arquivo, se ele existir, e, portanto, não precisar abri-lo, faça
if os.path.isfile(filepath):
os.rename(filepath, filepath + '.old')
Se você deseja gravar em um arquivo, se ele não existir, faça
# 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'
Se você precisar de bloqueio de arquivos, isso será diferente.
os.path.exists
retorna true para itens que não são arquivos, como diretórios. Isso dá falsos positivos. Veja as outras respostas recomendadas os.path.isfile
.
filepath
com o tempo certo, e BAM , você substitui o arquivo de destino. Você deve fazer open(filepath, 'wx')
em um try...except
bloco para evitar o problema.
OSError
se filepath + '.old'
já existir: "No Windows, se o dst já existir, o OSError será gerado mesmo que seja um arquivo; pode não haver maneira de implementar uma renomeação atômica quando o dst nomeia um arquivo existente ".
os.replace
realiza uma substituição silenciosa do arquivo de destino (é idêntico ao os.rename
comportamento do Linux) (apenas erros se o nome do destino existir e for um diretório). Portanto, você está preso no 2.x, mas os usuários do Py3 têm uma boa opção há vários anos.
rename
exemplo: ainda deve ser feito com try
/ except
. os.rename
(ou os.replace
no Python moderno) é atômico; fazê-lo verificar e renomear introduz uma corrida desnecessária e chamadas de sistema adicionais. Apenas façatry: os.replace(filepath, filepath + '.old') except OSError: pass
Você pode tentar isso (mais seguro):
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))
A saída seria:
([Erro 2] Não existe esse arquivo ou diretório: 'Whatever.txt')
Então, dependendo do resultado, seu programa pode continuar em execução a partir daí ou você pode codificar para pará-lo, se desejar.
try
Embora eu sempre recomende usar try
e except
instruções, aqui estão algumas possibilidades para você (meu favorito pessoal é usar os.access
):
Tente abrir o arquivo:
A abertura do arquivo sempre verificará a existência do arquivo. Você pode criar uma função da seguinte maneira:
def File_Existence(filepath):
f = open(filepath)
return True
Se for False, interromperá a execução com um IOError ou OSError sem tratamento nas versões posteriores do Python. Para capturar a exceção, você deve usar uma tentativa, exceto a cláusula. Obviamente, você sempre pode usar uma try
declaração exceto `assim (obrigado a hsandt
por me fazer pensar):
def File_Existence(filepath):
try:
f = open(filepath)
except IOError, OSError: # Note OSError is for later versions of Python
return False
return True
Use os.path.exists(path)
:
Isso verificará a existência do que você especificar. No entanto, ele verifica se há arquivos e diretórios, portanto, tenha cuidado com o uso.
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
Use os.access(path, mode)
:
Isso verificará se você tem acesso ao arquivo. Ele irá verificar as permissões. Com base na documentação do os.py, ao digitar os.F_OK
, ele verificará a existência do caminho. No entanto, usar isso criará uma brecha na segurança, pois alguém pode atacar seu arquivo usando o tempo entre verificar as permissões e abrir o arquivo. Você deve ir diretamente para abrir o arquivo em vez de verificar suas permissões. ( EAFP vs LBYP ). Se você não abrir o arquivo posteriormente e apenas verificar sua existência, poderá usá-lo.
Enfim, aqui:
>>> import os
>>> os.access("/is/a/file.txt", os.F_OK)
True
Também devo mencionar que existem duas maneiras pelas quais você não poderá verificar a existência de um arquivo. A questão será permission denied
ou no such file or directory
. Se você pegar um IOError
, defina o IOError as e
(como minha primeira opção) e digite print(e.args)
para que você possa determinar o problema. Espero que ajude! :)
Data: 2017-12-04
Todas as soluções possíveis foram listadas em outras respostas.
Uma maneira intuitiva e discutível de verificar se existe um arquivo é o seguinte:
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')
Fiz uma folha de dicas exaustiva para sua referência:
#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']}
Se o arquivo for para abrir, você poderá usar uma das seguintes técnicas:
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!')
ATUALIZAR
Apenas para evitar confusão e com base nas respostas que recebi, a resposta atual localiza um arquivo ou um diretório com o nome fornecido.
os.path.exists
retorna true para itens que não são arquivos, como diretórios. Isso dá falsos positivos. Veja as outras respostas recomendadas os.path.isfile
.
if os.path.isfile(path_to_file):
try:
open(path_to_file)
pass
except IOError as e:
print "Unable to open file"
Criar exceções é considerado uma abordagem aceitável e pitônica para controle de fluxo em seu programa. Considere manipular arquivos ausentes com IOErrors. Nessa situação, uma exceção IOError será gerada se o arquivo existir, mas o usuário não tiver permissões de leitura.
Você pode escrever a sugestão de Brian sem o try:
.
from contextlib import suppress
with suppress(IOError), open('filename'):
process()
suppress
faz parte do Python 3.4. Em versões mais antigas, você pode escrever rapidamente sua própria supressão:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
Sou o autor de um pacote que existe há cerca de 10 anos e tem uma função que aborda essa questão diretamente. Basicamente, se você estiver em um sistema não Windows, ele será usado Popen
para acessar find
. No entanto, se você estiver no Windows, ele se replica find
com um andador eficiente do sistema de arquivos.
O código em si não usa um try
bloco ... exceto para determinar o sistema operacional e, assim, direcioná-lo para o estilo "Unix" find
ou para o manual find
. Os testes de tempo mostraram que o processo de try
determinação do sistema operacional foi mais rápido, então eu usei um lá (mas em nenhum outro lugar).
>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']
E o doc…
>>> 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']
>>>
A implementação, se você preferir, está aqui: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190
Você pode seguir estas três maneiras:
Nota1:
os.path.isfile
Utilizado apenas para arquivos
import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists
Nota2: O
os.path.exists
usado para arquivos e diretórios
import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists
O
pathlib.Path
método (incluído no Python 3+, instalável com pip para Python 2)
from pathlib import Path
Path(filename).exists()
Adicionando mais uma ligeira variação que não é exatamente refletida nas outras respostas.
Isso manipulará o caso do file_path
ser None
ou da sequência vazia.
def file_exists(file_path):
if not file_path:
return False
elif not os.path.isfile(file_path):
return False
else:
return True
Adicionando uma variante com base na sugestão do Shahbaz
def file_exists(file_path):
if not file_path:
return False
else:
return os.path.isfile(file_path)
Adicionando uma variante com base na sugestão de Peter Wood
def file_exists(file_path):
return file_path and os.path.isfile(file_path):
if (x) return true; else return false;
é realmente justo return x
. Suas últimas quatro linhas podem se tornar return os.path.isfile(file_path)
. Enquanto estamos nisso, toda a função pode ser simplificada como return file_path and os.path.isfile(file_path)
.
return x
no caso de if (x)
. O Python considerará uma string vazia False; nesse caso, retornaríamos uma string vazia em vez de um bool. O objetivo desta função é sempre retornar bool.
x
é os.path.isfile(..)
assim que já é booleano.
os.path.isfile(None)
gera uma exceção e foi por isso que adicionei o if check. Eu provavelmente poderia envolvê-lo em uma tentativa / exceto em vez disso, mas achei que era mais explícito dessa maneira.
return file_path and os.path.isfile(file_path)
Aqui está um comando Python de 1 linha para o ambiente de linha de comando do Linux. Acho isso MUITO HANDY, já que não sou um cara gostoso do Bash.
python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"
Espero que isto seja útil.
[ -f "${file}" ] && echo "file found" || echo "file not found"
(que é igual a if [ ... ]; then ...; else ...; fi
).
Você pode usar a biblioteca "OS" do Python:
>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt")
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False
os.path.exists
retorna true para itens que não são arquivos, como diretórios. Isso dá falsos positivos. Veja as outras respostas recomendadas os.path.isfile
.
exists
bem. Se o objetivo é determinar se é seguro abrir um arquivo presumivelmente existente, as críticas são justificadas e existem não são suficientemente precisas. Infelizmente, o OP não especifica qual é o objetivo desejado (e provavelmente não o fará mais).
Como verifico se existe um arquivo sem usar a instrução try?
Em 2016, essa ainda é a maneira mais fácil de verificar se existe um arquivo e se é um arquivo:
import os
os.path.isfile('./file.txt') # Returns True if exists, else False
isfile
é realmente apenas um método auxiliar que usa internamente os.stat
e stat.S_ISREG(mode)
por baixo. Este os.stat
é um método de nível inferior que fornecerá informações detalhadas sobre arquivos, diretórios, soquetes, buffers e muito mais. Mais sobre o os.stat aqui
Nota: No entanto, essa abordagem não bloqueia o arquivo de maneira alguma e, portanto, seu código pode ficar vulnerável a erros de " verificação do tempo de uso " ( TOCTTOU ).
Portanto, criar exceções é considerado uma abordagem aceitável e pitônica para controle de fluxo em seu programa. E deve-se considerar manipular arquivos ausentes com IOErrors, em vez de if
instruções ( apenas um conselho ).
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)
isReadableFile(path,fileName)
vai voltar True
se o arquivo está acessível e legível pelo processo \ Programas \ fio