¿Cómo verifico si un archivo existe o no, sin usar la try
declaración?
fuente
¿Cómo verifico si un archivo existe o no, sin usar la try
declaración?
Si la razón por la que está verificando es para que pueda hacer algo como if file_exists: open_it()
, es más seguro usar un try
intento de abrirlo. Verificar y luego abrir se arriesga a que el archivo se elimine o se mueva o algo entre cuando lo verifique y cuando intente abrirlo.
Si no planea abrir el archivo de inmediato, puede usar os.path.isfile
Devuelve
True
si la ruta es un archivo regular existente. Esto sigue los enlaces simbólicos, por lo que tanto islink () como isfile () pueden ser verdaderos para la misma ruta.
import os.path
os.path.isfile(fname)
si necesita estar seguro de que es un archivo
Comenzando con Python 3.4, el pathlib
módulo ofrece un enfoque orientado a objetos (respaldado pathlib2
en Python 2.7):
from pathlib import Path
my_file = Path("/path/to/file")
if my_file.is_file():
# file exists
Para verificar un directorio, haga:
if my_file.is_dir():
# directory exists
Para verificar si un Path
objeto existe independientemente de si es un archivo o directorio, use exists()
:
if my_file.exists():
# path exists
También puedes usar resolve(strict=True)
en un try
bloque:
try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
FileNotFoundError
se introdujo en Python 3. Si también necesita admitir Python 2.7 y Python 3, puede usarIOError
en su lugar (quéFileNotFoundError
subclases) stackoverflow.com/a/21368457/1960959open('file', 'r+')
) y luego buscar hasta el final.Tienes la
os.path.exists
función:Esto devuelve
True
tanto para archivos como para directorios, pero en su lugar puede usarpara probar si es un archivo específicamente. Sigue los enlaces simbólicos.
fuente
A diferencia
isfile()
,exists()
volveráTrue
para los directorios. Entonces, dependiendo de si solo desea archivos simples o también directorios, usaráisfile()
oexists()
. Aquí hay una salida REPL simple:fuente
fuente
Usar
os.path.isfile()
conos.access()
:fuente
os.access()
devolverá falso.import os
usted no necesitaimport os.path
volver a hacerlo, ya que ya forma parte de élos
. Solo necesita importaros.path
si solo va a usar funciones deos.path
y no deos
sí mismo, para importar algo más pequeño, pero a medida que usaos.access
yos.R_OK
, la segunda importación no es necesaria.fuente
Aunque casi todas las formas posibles se han enumerado en (al menos una de) las respuestas existentes (por ejemplo, se agregaron cosas específicas de Python 3.4 ), intentaré agrupar todo.
Nota : cada parte del código de la biblioteca estándar de Python que voy a publicar pertenece a la versión 3.5.3 .
Declaración del problema :
Posibles soluciones :
[Python 3]: os.path. que existe ( ruta ) (también comprobar otros miembros de la familia como función
os.path.isfile
,os.path.isdir
,os.path.lexists
de comportamientos ligeramente diferentes)Todo bien, pero si sigue el árbol de importación:
os.path
- posixpath.py ( ntpath.py )genericpath.py , línea ~ # 20 +
es solo un bloque try / except alrededor de [Python 3]: os. stat ( ruta, *, dir_fd = Ninguno, follow_symlinks = Verdadero ) . Entonces, su código es try / except free, pero más abajo en el stackstack hay (al menos) uno de esos bloques. Esto también se aplica a otros funcs ( incluidos
os.path.isfile
).1.1. [Python 3]: Camino. is_file ()
Debajo del capó, hace exactamente lo mismo ( pathlib.py , línea ~ # 1330 ):
[Python 3]: con gestores de contexto de declaración . Ya sea:
Crea uno:
Y su uso: replicaré el
os.path.isfile
comportamiento (tenga en cuenta que esto es solo para fines de demostración, no intente escribir dicho código para la producción ):Utilice [Python 3]: contextlib. suprimir ( * excepciones ) - que fue diseñado específicamente para suprimir selectivamente excepciones
Pero, parecen ser envoltorios sobre bloques try / except / else / finally , como [Python 3]: La declaración with dice:
Funciones transversales del sistema de archivos (y busque los resultados para elementos coincidentes)
[Python 3]: os. listdir ( ruta = '.' ) (o [Python 3]: os. scandir ( ruta = '.' ) en Python v 3.5 +, backport: [PyPI]: scandir )
Debajo del capó, ambos usan:
a través de [GitHub]: python / cpython - (maestro) cpython / Modules / posixmodule.c
os.listdir
(os.scandir
cuando esté disponible)glob.glob
)os.listdir
Dado que estos iteran sobre las carpetas (en la mayoría de los casos) son ineficientes para nuestro problema (hay excepciones, como el bing de globo no comodín , como señaló @ShadowRanger), por lo que no voy a insistir en ellos. Sin mencionar que en algunos casos, el procesamiento del nombre de archivo puede ser requerido.
[Python 3]: os. de acceso ( path, el modo, *, dir_fd = ninguno, effective_ids = False, follow_symlinks = true ) cuyo comportamiento está cerca
os.path.exists
(en realidad es más amplia, principalmente debido a la 2 ª argumento)os.access("/tmp", os.F_OK)
Desde También trabajo en C , utilizo este método, así porque bajo el capó, llama a nativo API s (de nuevo, a través de "$ {} PYTHON_SRC_DIR /Modules/posixmodule.c" ), pero también abre una puerta para un posible usuario errores , y no es tan Python ic como otras variantes. Entonces, como señaló correctamente @AaronHall, no lo use a menos que sepa lo que está haciendo:
Nota : también es posible llamar a API s nativas a través de [Python 3]: ctypes : una biblioteca de funciones foráneas para Python , pero en la mayoría de los casos es más complicada.
( Win específico): dado que vcruntime * ( msvcr * ) .dll exporta una [MS.Docs]: _access, _waccess function family también, aquí hay un ejemplo:
Notas :
os.F_OK
en la llamada, pero eso es solo por claridad (su valor es 0 )La contraparte de Lnx ( Ubtu (16 x64) ) también:
Notas :
En lugar de codificar la ruta de libc ( "/lib/x86_64-linux-gnu/libc.so.6" ) que puede (y muy probablemente variará) entre sistemas, Ninguno (o la cadena vacía) se puede pasar al constructor CDLL (
ctypes.CDLL(None).access(b"/tmp", os.F_OK)
) De acuerdo con [man7]: DLOPEN (3) :__declspec(dllexport)
(¿por qué demonios la persona normal haría eso?), el programa principal es cargable pero prácticamente inutilizableInstalar algún módulo de terceros con capacidades de sistema de archivos
Lo más probable es que dependa de una de las formas anteriores (tal vez con ligeras personalizaciones).
Un ejemplo sería (nuevamente, Win específico) [GitHub]: mhammond / pywin32 - Python para Windows (pywin32) Extensiones , que es un contenedor de Python sobre WINAPI .
Pero, dado que esto es más como una solución, me detengo aquí.
Otra solución (poco convincente ) ( gainarie ) es (como me gusta llamarlo) el enfoque sysadmin : use Python como envoltorio para ejecutar comandos de shell
Ganar :
Nix ( Lnx ( Ubtu )):
Línea inferior :
Nota (s) final (es) :
fuente
glob.iglob
(yglob.glob
también) se basan enos.scandir
, por lo que ahora es vago; para obtener el primer hit en un directorio de archivos de 10M, solo escanea hasta llegar al primer hit. E incluso antes de 3.6, si usaglob
métodos sin comodines, la función es inteligente: sabe que solo puede tener un golpe, por lo que simplifica el globbing a soloos.path.isdir
oos.path.lexists
(dependiendo de si la ruta termina/
).os.path.isdir
oos.path.lexist
ya que es un montón de llamadas a funciones de nivel Python y cadena operaciones antes de que decida que la ruta eficiente es viable, pero no se requiere una llamada adicional al sistema o trabajo de E / S, que es un orden de magnitud más lento).Esta es la forma más sencilla de verificar si existe un archivo. El hecho de que el archivo existiera cuando lo verificó no garantiza que estará allí cuando necesite abrirlo.
fuente
Python 3.4+ tiene un módulo de ruta orientado a objetos: pathlib . Con este nuevo módulo, puede verificar si existe un archivo como este:
Puede (y generalmente debería) seguir usando un
try/except
bloque al abrir archivos:El módulo pathlib tiene un montón de cosas interesantes en él: engorde conveniente, comprobación del propietario del archivo, unión de ruta más fácil, etc. Vale la pena echarle un vistazo. Si está en una Python anterior (versión 2.6 o posterior), aún puede instalar pathlib con pip:
Luego impórtelo de la siguiente manera:
fuente
Prefiere la declaración de prueba. Se considera mejor estilo y evita las condiciones de carrera.
No confíes en mi palabra. Hay mucho apoyo para esta teoría. Aquí hay una pareja:
fuente
try...except
no ayuda a resolver ese problema de todos modos.except:
cláusula hará que una excepción que surja en esta parte de su código genere un mensaje confuso (se produce un segundo error durante el procesamiento del primero.)Ahora disponible desde Python 3.4, importe e instancia un
Path
objeto con el nombre del archivo y verifique elis_file
método (tenga en cuenta que esto devuelve True para los enlaces simbólicos que apuntan también a archivos normales):Si está en Python 2, puede hacer una copia de seguridad del módulo pathlib desde pypi
pathlib2
, o verificarisfile
desde elos.path
módulo:Ahora, lo anterior es probablemente la mejor respuesta directa pragmática aquí, pero existe la posibilidad de una condición de carrera (dependiendo de lo que esté tratando de lograr), y el hecho de que la implementación subyacente usa un
try
, pero Python usatry
en todas partes en su implementación.Debido a que Python se usa en
try
todas partes, realmente no hay razón para evitar una implementación que lo use.Pero el resto de esta respuesta intenta considerar estas advertencias.
Respuesta más larga y mucho más pedante
Disponible desde Python 3.4, use el nuevo
Path
objeto enpathlib
. Tenga en cuenta que.exists
no es del todo correcto, porque los directorios no son archivos (excepto en el sentido de Unix de que todo es un archivo).Entonces necesitamos usar
is_file
:Aquí está la ayuda sobre
is_file
:Entonces obtengamos un archivo que sabemos que es un archivo:
De forma predeterminada,
NamedTemporaryFile
elimina el archivo cuando se cierra (y se cerrará automáticamente cuando no existan más referencias).Sin embargo, si profundiza en la implementación , verá que
is_file
utilizatry
:Condiciones de carrera: por qué nos gusta probar
Nos gusta
try
porque evita las condiciones de carrera. Contry
, simplemente intentas leer tu archivo, esperando que esté allí, y si no, capturas la excepción y realizas cualquier comportamiento alternativo que tenga sentido.Si desea verificar que existe un archivo antes de intentar leerlo, y podría estar borrándolo y luego podría estar usando múltiples hilos o procesos, u otro programa conoce ese archivo y podría borrarlo; corre el riesgo de la posibilidad de una condición de carrera si verifica que existe, porque entonces está corriendo para abrirla antes de que cambie su condición (su existencia).
Las condiciones de carrera son muy difíciles de depurar porque hay una ventana muy pequeña en la que pueden hacer que su programa falle.
Pero si esta es su motivación, puede obtener el valor de una
try
declaración utilizando elsuppress
administrador de contexto.Evitar condiciones de carrera sin una declaración de prueba:
suppress
Python 3.4 nos da el
suppress
administrador de contexto (anteriormente elignore
administrador de contexto), que hace semánticamente exactamente lo mismo en menos líneas, mientras que también (al menos superficialmente) cumple con la solicitud original para evitar unatry
declaración:Uso:
Para Pythons anteriores, puedes tirar el tuyo
suppress
, pero sin untry
will será más detallado que con. Creo que esta es la única respuesta que no se usatry
en ningún nivel en Python a la que se pueda aplicar antes de Python 3.4 porque en su lugar usa un administrador de contexto:Quizás más fácil con un intento:
Otras opciones que no cumplen con la solicitud de "sin probar":
isfile
de los documentos :
Pero si examina el origen de esta función, verá que en realidad usa una instrucción try:
Todo lo que está haciendo es usar la ruta dada para ver si puede obtener estadísticas, capturar
OSError
y luego verificar si es un archivo si no generó la excepción.Si tiene la intención de hacer algo con el archivo, le sugiero que intente directamente con una prueba, excepto para evitar una condición de carrera:
os.access
Está disponible para Unix y Windows
os.access
, pero para usar debe pasar banderas, y no diferencia entre archivos y directorios. Esto se usa más para probar si el usuario real que invoca tiene acceso en un entorno de privilegios elevados:También sufre los mismos problemas de condición de carrera que
isfile
. De los documentos :Evitar el uso
os.access
. Es una función de bajo nivel que tiene más oportunidades para el error del usuario que los objetos y funciones de nivel superior discutidos anteriormente.Crítica de otra respuesta:
Otra respuesta dice esto sobre
os.access
:Esta respuesta dice que prefiere un método no pitónico, propenso a errores, sin justificación. Parece alentar a los usuarios a utilizar API de bajo nivel sin comprenderlos.
También crea un administrador de contexto que, al regresar incondicionalmente
True
, permite que todas las Excepciones (incluidasKeyboardInterrupt
ySystemExit
!) Pasen en silencio, lo cual es una buena manera de ocultar errores.Esto parece alentar a los usuarios a adoptar malas prácticas.
fuente
La importación
os
facilita la navegación y la realización de acciones estándar con su sistema operativo.Para referencia también vea ¿Cómo verificar si un archivo existe usando Python?
Si necesita operaciones de alto nivel, use
shutil
.fuente
os.path.exists
devuelve verdadero para cosas que no son archivos, como directorios. Esto da falsos positivos. Vea las otras respuestas que recomiendanos.path.isfile
.Prueba de archivos y carpetas con
os.path.isfile()
,os.path.isdir()
yos.path.exists()
Suponiendo que la "ruta" es una ruta válida, esta tabla muestra lo que devuelve cada función para archivos y carpetas:
También puede probar si un archivo es un determinado tipo de archivo
os.path.splitext()
para obtener la extensión (si aún no lo sabe)fuente
En 2016, la mejor manera sigue usando
os.path.isfile
:O en Python 3 puedes usar
pathlib
:fuente
pathlib
es la solución OOP de python para caminos. Puedes hacer mucho más con eso. Si solo necesita verificar la existencia, la ventaja no es tan grande.No parece que haya una diferencia funcional significativa entre try / except y
isfile()
, por lo que debe usar cuál tiene sentido.Si desea leer un archivo, si existe, haga
Pero si solo desea cambiar el nombre de un archivo si existe y, por lo tanto, no necesita abrirlo, haga
Si desea escribir en un archivo, si no existe, haga
Si necesita bloqueo de archivos, ese es un asunto diferente.
fuente
os.path.exists
devuelve verdadero para cosas que no son archivos, como directorios. Esto da falsos positivos. Vea las otras respuestas que recomiendanos.path.isfile
.filepath
con el tiempo correcto, y BAM , sobrescribe el archivo de destino. Debe hacerloopen(filepath, 'wx')
entry...except
bloque para evitar el problema.OSError
iffilepath + '.old'
ya existe: "En Windows, si dst ya existe, se generará OSError incluso si es un archivo; puede que no haya forma de implementar un cambio de nombre atómico cuando dst nombra un archivo existente ".os.replace
realiza de forma portátil la sustitución silenciosa del archivo de destino (es idéntico alos.rename
comportamiento de Linux de Linux) (solo produce errores si el nombre de destino existe y es un directorio). Así que estás atascado en 2.x, pero los usuarios de Py3 han tenido una buena opción durante varios años.rename
ejemplo: aún debe hacerse contry
/except
.os.rename
(oos.replace
en Python moderno) es atómico; hacer que se verifique y luego cambiar el nombre introduce una carrera innecesaria y llamadas adicionales al sistema. Just dotry: os.replace(filepath, filepath + '.old') except OSError: pass
Podrías probar esto (más seguro):
La salida sería:
Luego, dependiendo del resultado, su programa puede seguir ejecutándose desde allí o puede codificar para detenerlo si lo desea.
fuente
try
Aunque siempre recomiendo usar
try
yexcept
declaraciones, aquí hay algunas posibilidades para usted (mi favorito personal es usaros.access
):Intenta abrir el archivo:
Abrir el archivo siempre verificará la existencia del archivo. Puedes hacer una función así:
Si es False, detendrá la ejecución con un IOError u OSError no administrado en versiones posteriores de Python. Para atrapar la excepción, debe utilizar una cláusula try excepto. Por supuesto, siempre puedes usar una
try
declaración except` como esta (gracias a hsandt por hacerme pensar):Uso
os.path.exists(path)
:Esto verificará la existencia de lo que especifique. Sin embargo, busca archivos y directorios, así que ten cuidado con cómo lo usas.
Uso
os.access(path, mode)
:Esto verificará si tiene acceso al archivo. Verificará los permisos. Según la documentación de os.py, al escribir
os.F_OK
, verificará la existencia de la ruta. Sin embargo, usar esto creará un agujero de seguridad, ya que alguien puede atacar su archivo usando el tiempo entre verificar los permisos y abrir el archivo. En su lugar, debe ir directamente a abrir el archivo en lugar de verificar sus permisos. ( EAFP vs LBYP ). Si no va a abrir el archivo después, y solo verifica su existencia, puede usar esto.De todos modos, aquí:
También debo mencionar que hay dos formas en que no podrá verificar la existencia de un archivo. O el problema será
permission denied
ono such file or directory
. Si detecta unIOError
, configure elIOError as e
(como mi primera opción), y luego escribaprint(e.args)
para que pueda determinar su problema. ¡Espero que ayude! :)fuente
Fecha: 2017-12-04
Todas las soluciones posibles se han enumerado en otras respuestas.
Una forma intuitiva y discutible de verificar si existe un archivo es la siguiente:
Hice una hoja de trucos exhaustiva para su referencia:
fuente
Si el archivo es para abrir, puede usar una de las siguientes técnicas:
ACTUALIZAR
Solo para evitar confusiones y según las respuestas que obtuve, la respuesta actual encuentra un archivo o un directorio con el nombre de pila.
fuente
os.path.exists
devuelve verdadero para cosas que no son archivos, como directorios. Esto da falsos positivos. Vea las otras respuestas que recomiendanos.path.isfile
.Además
os.access()
:Being
R_OK
,W_OK
yX_OK
las banderas para probar los permisos ( doc ).fuente
SRC: http://www.pfinn.net/python-check-if-file-exists.html
fuente
Si ha importado NumPy ya para otros fines, entonces no hay necesidad de importar otras bibliotecas como
pathlib
,os
,paths
, etc.Esto devolverá verdadero o falso basado en su existencia.
fuente
Puedes escribir la sugerencia de Brian sin el
try:
.suppress
es parte de Python 3.4. En versiones anteriores, puede escribir rápidamente su propia supresión:fuente
Soy el autor de un paquete que existe desde hace aproximadamente 10 años, y tiene una función que aborda esta pregunta directamente. Básicamente, si está en un sistema que no es Windows, se utiliza
Popen
para accederfind
. Sin embargo, si está en Windows, se replicafind
con un eficiente caminante de sistema de archivos.El código en sí no usa un
try
bloque ... excepto para determinar el sistema operativo y así dirigirlo al estilo "Unix"find
o al buillt manualfind
. Las pruebas de tiempo mostraron quetry
era más rápido para determinar el sistema operativo, por lo que utilicé uno allí (pero en ningún otro lugar).Y el doctor ...
La implementación, si quiere mirar, está aquí: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190
fuente
Comprobar archivo o directorio existe
Puedes seguir estas tres formas:
fuente
Agregar una ligera variación más que no se refleja exactamente en las otras respuestas.
Esto manejará el caso del
file_path
serNone
o cadena vacía.Agregar una variante basada en la sugerencia de Shahbaz
Agregar una variante basada en la sugerencia de Peter Wood
fuente
if (x) return true; else return false;
es en realidadreturn x
. Tus últimas cuatro líneas pueden convertirsereturn os.path.isfile(file_path)
. Mientras estamos en ello, toda la función se puede simplificar comoreturn file_path and os.path.isfile(file_path)
.return x
en el caso deif (x)
. Python considerará una cadena vacía Falso, en cuyo caso estaríamos devolviendo una cadena vacía en lugar de un bool. El propósito de esta función es devolver siempre bool.x
esos.path.isfile(..)
así que ya es bool.os.path.isfile(None)
plantea una excepción, por eso agregué el if check. Probablemente podría envolverlo en un intento / excepto en su lugar, pero sentí que era más explícito de esta manera.return file_path and os.path.isfile(file_path)
Aquí hay un comando Python de 1 línea para el entorno de línea de comandos de Linux. Encuentro esto MUY PRÁCTICO ya que no soy un tipo Bash tan bueno.
Espero que esto sea útil.
fuente
[ -f "${file}" ] && echo "file found" || echo "file not found"
(que es lo mismo queif [ ... ]; then ...; else ...; fi
).Puede usar la biblioteca "OS" de Python:
fuente
os.path.exists
devuelve verdadero para cosas que no son archivos, como directorios. Esto da falsos positivos. Vea las otras respuestas que recomiendanos.path.isfile
.exists
está bien. Si el objetivo es determinar si es seguro abrir un archivo presumiblemente existente, entonces la crítica está justificada y existe no es lo suficientemente precisa. Lamentablemente, el OP no especifica cuál es el objetivo deseado (y probablemente ya no lo hará).En 2016, esta podría ser la forma más fácil de verificar si existe un archivo y si es un archivo:
isfile
en realidad es solo un método auxiliar que usa internamenteos.stat
ystat.S_ISREG(mode)
debajo. Esteos.stat
es un método de nivel inferior que le proporcionará información detallada sobre archivos, directorios, sockets, buffers y más. Más acerca de os.stat aquíNota: Sin embargo, este enfoque no bloqueará el archivo de ninguna manera y, por lo tanto, su código puede volverse vulnerable al " tiempo de verificación hasta el momento de uso " ( TOCTTOU errores de ).
Por lo tanto, aumentar las excepciones se considera un enfoque aceptable y Pythonic para el control de flujo en su programa. Y uno debería considerar manejar archivos perdidos con IOErrors, en lugar de
if
declaraciones ( solo un consejo ).fuente
fuente
isReadableFile(path,fileName)
volveráTrue
si el archivo es accesible y legible por el proceso \ program \ thread