Abrir documento con aplicación predeterminada en Python

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 icono del documento en Explorer o Finder. ¿Cuál es la mejor manera de hacer esto en Python?

En Mac OS, puedes usar el comando “abrir”. Hay una llamada a la API de Windows que hace algo similar, pero no lo recuerdo de antemano.

Actualizar

De acuerdo, el comando de “inicio” lo hará, así que esto debería funcionar.

Mac OS X:

os.system("open "+filename) 

Windows:

 os.system("start "+filename) 

La actualización posterior de Edward: os.system funciona mucho, pero solo funciona con nombres de archivos que no tienen espacios en las carpetas y archivos en el nombre del archivo (por ejemplo, A: \ abc \ def \ a.txt) .

Actualización posterior

Bien, claramente esta tonta controversia continúa, así que veamos cómo hacer esto con el subproceso.

open y start son cosas del intérprete de comandos para Mac OS / X y Windows respectivamente. Ahora, digamos que usamos subproceso. Canónicamente, utilizarías:

 try: retcode = subprocess.call("open " + filename, shell=True) if retcode < 0: print >>sys.stderr, "Child was terminated by signal", -retcode else: print >>sys.stderr, "Child returned", retcode except OSError, e: print >>sys.stderr, "Execution failed:", e 

Ahora, ¿cuáles son las ventajas de esto? En teoría, esto es más seguro, pero de hecho necesitamos ejecutar una línea de comando de una forma u otra; en cualquier entorno, necesitamos el entorno y los servicios para interpetar, obtener rutas, etc. En ningún caso estamos ejecutando texto arbitrario, por lo que no tiene un problema inherente “pero puede escribir 'filename ; rm -rf /' “, y SI el nombre del archivo puede estar dañado, el uso de subprocess.call no nos brinda protección .

En realidad, no nos da más detección de errores, aún estamos dependiendo del retcode de retcode en cualquier caso. No tenemos que esperar al proceso secundario, ya que estamos ante una statement de problemas que comienza un proceso separado.

“Pero se prefiere el subprocess “. Sin embargo, os.system() no está en desuso, y es la herramienta más sencilla para este trabajo en particular.

Conclusión: usar os.system() es la forma más sencilla y directa de hacer esto, y por lo tanto es una respuesta correcta.

Utilice el módulo de subprocess disponible en Python 2.4+, no os.system() , para no tener que lidiar con el escape de shell.

 import subprocess, os, platform if platform.system() == 'Darwin': # macOS subprocess.call(('open', filepath)) elif platform.system() == 'Windows': # Windows os.startfile(filepath) else: # linux variants subprocess.call(('xdg-open', filepath)) 

Los paréntesis dobles se deben a que subprocess.call() quiere una secuencia como primer argumento, por lo que estamos usando una tupla aquí. En los sistemas Linux con Gnome también hay un comando gnome-open que hace lo mismo, pero xdg-open es el estándar de Free Desktop Foundation y funciona en entornos de escritorio Linux.

Yo prefiero:

 os.startfile(path, 'open') 

Tenga en cuenta que este módulo admite nombres de archivo que tienen espacios en sus carpetas y archivos, por ejemplo

 A:\abc\folder with spaces\file with-spaces.txt 

( documentos de Python ) ‘abrir’ 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.

Solo para estar completo (no estaba en la pregunta), xdg-open hará lo mismo en Linux.

 import os import subprocess def click_on_file(filename): '''Open document with default application in Python.''' try: os.startfile(filename) except AttributeError: subprocess.call(['open', filename]) 

Si tiene que usar un método heurístico, puede considerar el webbrowser .
Es una biblioteca estándar y, a pesar de su nombre, también intentará abrir archivos:

Tenga en cuenta que en algunas plataformas, al intentar abrir un nombre de archivo utilizando esta función, puede funcionar e iniciar el progtwig asociado del sistema operativo. Sin embargo, esto no es compatible ni portátil. ( Referencia )

Probé este código y funcionó bien en Windows 7 y Ubuntu Natty:

 import webbrowser webbrowser.open("path_to_file") 

Este código también funciona bien en Windows XP Professional, utilizando Internet Explorer 8.

El inicio no admite nombres de ruta largos y espacios en blanco. Tienes que convertirlo a 8.3 rutas compatibles.

 import subprocess import win32api filename = "C:\\Documents and Settings\\user\\Desktop\file.avi" filename_short = win32api.GetShortPathName(filename) subprocess.Popen('start ' + filename_short, shell=True ) 

El archivo debe existir para poder trabajar con la llamada a la API.

Si quieres ir a la manera subprocess.call() , debería verse así en Windows:

 import subprocess subprocess.call(('cmd', '/C', 'start', '', FILE_NAME)) 

No puedes simplemente usar:

 subprocess.call(('start', FILE_NAME)) 

porque start no es un ejecutable sino un comando del progtwig cmd.exe . Esto funciona:

 subprocess.call(('cmd', '/C', 'start', FILE_NAME)) 

pero solo si no hay espacios en el ARCHIVO_NOMBRE.

Mientras el método subprocess.call en cita los parámetros correctamente, el comando de start tiene una syntax bastante extraña, donde:

 start notes.txt 

hace algo más que

 start "notes.txt" 

La primera cadena entre comillas debe establecer el título de la ventana. Para que funcione con espacios, tenemos que hacer:

 start "" "my notes.txt" 

que es lo que hace el código en la parte superior.

Estoy bastante tarde para el lote, pero aquí hay una solución usando la API de Windows. Esto siempre abre la aplicación asociada.

 import ctypes shell32 = ctypes.windll.shell32 file = 'somedocument.doc' shell32.ShellExecuteA(0,"open",file,0,0,5) 

Muchas constantes mágicas. El primer cero es el hwnd del progtwig 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 de ShellExecute para obtener más información.

os.startfile (ruta, ‘abrir’) bajo windows es bueno porque cuando existen espacios en el directorio, os.system (‘inicio’, ruta_de_ruta) no puede abrir la aplicación correcta y cuando existe el i18n en el directorio, os. El sistema necesita cambiar el código Unicode al códec de la consola en Windows.

en mac os puedes llamar ‘abierto’

 import os os.popen("open myfile.txt") 

esto abriría el archivo con TextEdit, o cualquier aplicación está configurada como predeterminada para este tipo de archivo

Si desea especificar la aplicación para abrir el archivo con Mac OS X, use esto: os.system("open -a [app name] [file name]")

En Windows 8.1, a continuación han funcionado, mientras que otras formas dadas con subprocess.call fallan con la ruta tiene espacios en ella.

 subprocess.call('cmd /c start "" "any file path with spaces"') 

Al utilizar esta y otras respuestas anteriores, aquí hay un código en línea que funciona en múltiples plataformas.

 import sys, os, subprocess subprocess.call(('cmd /c start "" "'+ filepath +'"') if os.name is 'nt' else ('open' if sys.platform.startswith('darwin') else 'xdg-open', filepath))