Necesito poder abrir un documento usando su aplicación predeterminada en Windows y Mac OS. Básicamente, quiero hacer lo mismo que sucede cuando haces doble clic en el ícono del documento en Explorer o Finder. ¿Cuál es la mejor manera de hacer esto en Python?
126
Respuestas:
open
ystart
son cosas de intérprete de comandos para Mac OS / X y Windows respectivamente, para hacer esto.Para llamarlos desde Python, puede usar
subprocess
module oos.system()
.Aquí hay consideraciones sobre qué paquete usar:
Puedes llamarlos a través de
os.system
, que funciona, pero ...Escapar:
os.system
solo funciona con nombres de archivo que no tienen espacios u otros metacaracteres de shell en el nombre de ruta (por ejemploA:\abc\def\a.txt
), o de lo contrario estos deben escaparse. Existeshlex.quote
para sistemas tipo Unix, pero nada realmente estándar para Windows. Quizás vea también python, windows: análisis de líneas de comando con shlexos.system("open " + shlex.quote(filename))
os.system("start " + filename)
en el que también sefilename
debe escapar correctamente hablando .También puede llamarlos a través del
subprocess
módulo, pero ...Para Python 2.7 y posteriores, simplemente use
En Python 3.5+ puedes usar de manera equivalente el más complejo pero también algo más versátil.
Si necesita ser compatible hasta Python 2.4, puede usar
subprocess.call()
e implementar su propia comprobación de errores:Ahora, ¿cuáles son las ventajas de usar
subprocess
?'filename ; rm -rf /'
", y si el nombre del archivo puede estar dañado, el usosubprocess.call
nos brinda poca protección adicional.retcode
casos; pero el comportamiento de generar explícitamente una excepción en el caso de un error ciertamente lo ayudará a notar si hay una falla (aunque en algunos escenarios, un rastreo puede no ser más útil que simplemente ignorar el error).A la objeción "Pero
subprocess
se prefiere". Sin embargo,os.system()
no está en desuso, y en cierto sentido es la herramienta más simple para este trabajo en particular. Conclusión: usandoos.system()
es, por lo tanto, también una respuesta correcta.Una desventaja marcada es que el
start
comando de Windows requiere que pase, loshell=True
que niega la mayoría de los beneficios del usosubprocess
.fuente
filename
venga la forma, este es un ejemplo perfecto de por qué os.system () es inseguro y malo. El subproceso es mejor.os.system()
es que usa el shell (y no está haciendo ningún escape de shell aquí, por lo que sucederán cosas malas para nombres de archivo perfectamente válidos que contengan metacaracteres de shell). La razón por la quesubprocess.call()
se prefiere es que tiene la opción de omitir el shell mediante el usosubprocess.call(["open", filename])
. Esto funciona para todos los nombres de archivo válidos, y no introduce una vulnerabilidad de inyección de shell incluso para nombres de archivo no confiables.Utilizar el
subprocess
módulo disponible en Python 2.4+, noos.system()
, para que no tenga que lidiar con el escape de shell.Los paréntesis dobles son porque
subprocess.call()
quiere una secuencia como primer argumento, así que estamos usando una tupla aquí. En los sistemas Linux con Gnome también hay ungnome-open
comando que hace lo mismo, peroxdg-open
es el estándar Free Desktop Foundation y funciona en entornos de escritorio Linux.fuente
xdg-open
- linux.die.net/man/1/xdg-openxdg-open test.py
y me abrió el diálogo de descarga de Firefox. Que pasa Estoy en Manjaro Linux.xdg-open
configuración es confusa, pero eso no es realmente algo que podamos solucionar en un comentario. Quizás vea unix.stackexchange.com/questions/36380/…Yo prefiero:
Tenga en cuenta que este módulo admite nombres de archivo que tienen espacios en sus carpetas y archivos, por ejemplo
( documentos de Python ) 'abierto' no tiene que agregarse (es el valor predeterminado). Los documentos mencionan específicamente que esto es como hacer doble clic en el icono de un archivo en el Explorador de Windows.
Esta solución es solo para Windows.
fuente
startfile
función ni siquiera existe, lo que significa que los usuarios recibirán un mensaje de error confuso sobre una función faltante. Es posible que desee comprobar la plataforma para evitar esto.Solo para completar (no estaba en la pregunta), xdg-open hará lo mismo en Linux.
fuente
fuente
Si tiene que usar un método heurístico, puede considerarlo
webbrowser
.Es una biblioteca estándar y, a pesar de su nombre, también intentaría abrir archivos:
Probé este código y funcionó bien en Windows 7 y Ubuntu Natty:
Este código también funciona bien en Windows XP Professional, utilizando Internet Explorer 8.
fuente
open location
allí que debería funcionar si proporciona la ruta como una URL válida.import webbrowser webbrowser.open("file:///Users/nameGoesHere/Desktop/folder/file.py")
Si desea seguir el
subprocess.call()
camino, debería verse así en Windows:No puedes simplemente usar:
porque
start
no es un ejecutable sino un comando delcmd.exe
programa. Esto funciona:pero solo si no hay espacios en FILE_NAME.
Si bien el
subprocess.call
métodoencita los parámetros correctamente, elstart
comando tiene una sintaxis bastante extraña, donde:hace algo más que:
La primera cadena entre comillas debe establecer el título de la ventana. Para que funcione con espacios, tenemos que hacer:
que es lo que hace el código de arriba.
fuente
Inicio no admite nombres de ruta largos y espacios en blanco. Tienes que convertirlo a 8.3 rutas compatibles.
El archivo tiene que existir para poder trabajar con la llamada API.
fuente
start "Title" "C:\long path to\file.avi"
Llego bastante tarde al lote, pero aquí hay una solución usando la API de Windows. Esto siempre abre la aplicación asociada.
Muchas constantes mágicas. El primer cero es el hwnd del programa actual. Puede ser cero. Los otros dos ceros son parámetros opcionales (parámetros y directorio). 5 == SW_SHOW, especifica cómo ejecutar la aplicación. Lea los documentos de la API ShellExecute para obtener más información.
fuente
os.startfile(file)
?en mac os puedes llamar 'abierto'
esto abriría el archivo con TextEdit, o cualquier aplicación que esté configurada como predeterminada para este tipo de archivo
fuente
Si desea especificar la aplicación para abrir el archivo en Mac OS X, use esto:
os.system("open -a [app name] [file name]")
fuente
En Windows 8.1, a continuación han funcionado, mientras que otras formas dadas con
subprocess.call
fallas con la ruta tienen espacios.Al utilizar esta y otras respuestas anteriores, aquí hay un código en línea que funciona en múltiples plataformas.
fuente
os.startfile(path, 'open')
en Windows es bueno porque cuando existen espacios en el directorio,os.system('start', path_name)
no se puede abrir la aplicación correctamente y cuando el i18n existe en el directorio,os.system
necesita cambiar el código Unicode al códec de la consola en Windows.fuente