operaciones - Compruebe los permisos de un archivo en python
operaciones con archivos python (1)
Estoy tratando de verificar la legibilidad de un archivo dada la ruta especificada. Esto es lo que tengo:
def read_permissions(filepath):
''''''Checks the read permissions of the specified file''''''
try:
os.access(filepath, os.R_OK) # Find the permissions using os.access
except IOError:
return False
return True
Esto funciona y devuelve True o False como salida cuando se ejecuta. Sin embargo, quiero que los mensajes de error de errno
acompañen. Esto es lo que creo que debería hacer (pero sé que hay algo mal):
def read_permissions(filepath):
''''''Checks the read permissions of the specified file''''''
try:
os.access(filepath, os.R_OK) # Find the permissions using os.access
except IOError as e:
print(os.strerror(e)) # Print the error message from errno as a string
print("File exists.")
Sin embargo, si tuviera que escribir un archivo que no existe, me dice que el archivo existe. ¿Puede alguien ayudarme en lo que he hecho mal (y qué puedo hacer para evitar este problema en el futuro)? No he visto a nadie probar esto usando os.access
. También estoy abierto a otras opciones para probar los permisos de un archivo. ¿Alguien me puede ayudar a plantear el mensaje de error apropiado cuando algo va mal?
Además, es probable que esto se aplique a mis otras funciones (Todavía usan os.access
cuando comprueban otras cosas, como la existencia de un archivo usando os.F_OK
y los permisos de escritura de un archivo usando os.W_OK
). Aquí hay un ejemplo del tipo de cosas que intento simular:
>>> read_permissions("located-in-restricted-directory.txt") # Because of a permission error (perhaps due to the directory)
[errno 13] Permission Denied
>>> read_permissions("does-not-exist.txt") # File does not exist
[errno 2] No such file or directory
Este es el tipo de cosas que estoy tratando de simular, devolviendo el mensaje de error apropiado al problema. Espero que esto ayude a evitar cualquier confusión sobre mi pregunta.
Probablemente debería señalar que, aunque he leído la documentación de os.access
, no estoy intentando abrir el archivo más tarde. Simplemente intento crear un módulo en el cual algunos de los componentes sean para verificar los permisos de un archivo en particular. Tengo una referencia (la primera pieza de código que mencioné) que sirve para tomar decisiones sobre el resto de mi código. Aquí, simplemente intento escribirlo de nuevo, pero de una manera fácil de usar (no solo True
o simplemente False
, sino más bien con mensajes completos). Dado que IOError
puede IOError
dos maneras diferentes (como permiso denegado o directorio inexistente), estoy intentando que mi módulo identifique y publique el problema. Espero que esto te ayude a ayudarme a determinar cualquier posible solución.
os.access
devuelve False
cuando el archivo no existe, independientemente del parámetro de modo que se haya pasado.
Esto no se menciona explícitamente en la documentación de os.access
pero no es un comportamiento terriblemente impactante; después de todo, si un archivo no existe, no es posible acceder a él. Verificar la página de manual de acceso (2) como lo sugieren los documentos da otra pista, en ese access
devuelve -1
en una amplia variedad de condiciones. En cualquier caso, puede simplemente hacer lo que hice y verificar el valor de retorno en IDLE:
>>> import os
>>> os.access(''does_not_exist.txt'', os.R_OK)
False
En Python generalmente se desaconseja revisar los tipos y cosas así antes de intentar realmente hacer cosas útiles. Esta filosofía a menudo se expresa con la inicialización EAFP, que significa Perdón más fácil de pedir que el permiso . Si vuelve a consultar los documentos, verá que esto es particularmente relevante en el presente caso:
Nota: Usar
access()
para verificar si un usuario está autorizado a, por ejemplo, abrir un archivo antes de hacerlo usandoopen()
crea un agujero de seguridad, porque el usuario puede explotar el corto intervalo de tiempo entre verificar y abrir el archivo para manipularlo. Es preferible usar técnicas de EAFP . Por ejemplo:
if os.access("myfile", os.R_OK): with open("myfile") as fp: return fp.read() return "some default data"
está mejor 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()
Si tiene otras razones para verificar los permisos que no sea cuestionar al usuario antes de llamar a open()
, puede consultar ¿Cómo puedo verificar si un archivo existe utilizando Python? para algunas sugerencias Recuerde que si realmente necesita que se raise
una excepción, siempre puede raise
usted mismo; no es necesario ir a buscar uno en la naturaleza.
Dado que IOError se puede mostrar de dos maneras diferentes (como permiso denegado o directorio inexistente), estoy intentando que mi módulo identifique y publique el problema.
Eso es lo que hace el segundo enfoque anterior. Ver:
>>> try:
... open(''file_no_existy.gif'')
... except IOError as e:
... pass
...
>>> e.args
(2, ''No such file or directory'')
>>> try:
... open(''unreadable.txt'')
... except IOError as e:
... pass
...
>>> e.args
(13, ''Permission denied'')
>>> e.args == (e.errno, e.strerror)
True
Pero debes elegir un enfoque o el otro. Si está pidiendo perdón, haga la cosa (abra el archivo) en un bloque try-except y trate las consecuencias adecuadamente. Si tiene éxito, entonces sabe que tuvo éxito porque no hay excepción.
Por otro lado, si pides permiso (también conocido como LBYL, Look Before You Leap ) en esto y en el otro sentido, todavía no sabes si puedes abrir el archivo exitosamente hasta que realmente lo hagas . ¿Qué pasa si el archivo se mueve después de comprobar sus permisos? ¿Qué pasa si hay un problema que no pensaste verificar?
Si aún desea solicitar permiso, no use try-except; no estás haciendo lo correcto, así que no vas a lanzar errores. En su lugar, use declaraciones condicionales con llamadas a os.access
como condición.