Abrir documento con la 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 el Explorador o Finder. ¿Cuál es la mejor manera de hacer esto en Python?

Author: Francesco Montesano, 2009-01-12

13 answers

En Mac OS, puede usar el comando "abrir". Hay una llamada a la API de Windows que hace algo similar, pero no lo recuerdo de repente.

Actualizar

Bien, el comando "start" lo hará, así que esto debería funcionar.

Mac OS/X:

os.system("open "+filename)

Ventanas:

os.system("start "+filename)

Mucho más tarde actualización por Edward: os.el sistema funciona, pero solo funciona con nombres de archivo que no tienen espacios en carpetas y archivos en el nombre de archivo (p. ej. A:\abc\def\a.txt) .

Actualización posterior

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

open y start son cosas de intérprete de comandos para Mac OS/X y Windows respectivamente. Ahora, digamos que usamos subproceso. Canónicamente, usarí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 but pero de hecho estamos necesitando ejecutar una línea de comandos de una manera u otra; en cualquier entorno, necesitamos el entorno y los servicios para interpetar, obtener rutas, y así sucesivamente. En ninguno de los dos casos 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, usar subprocess.call no nos da protección.

En realidad no nos da más detección de errores, todavía estamos dependiendo de la retcode en cualquier caso. No necesitamos esperar por el proceso hijo, ya que estamos por la declaración del problema proceso separado.

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

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

 61
Author: Charlie Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-19 13:05:50

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

import subprocess, os
if sys.platform.startswith('darwin'):
    subprocess.call(('open', filepath))
elif os.name == 'nt': # For Windows
    os.startfile(filepath)
elif os.name == 'posix': # For Linux, Mac, etc.
    subprocess.call(('xdg-open', filepath))

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

 118
Author: Nick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-25 20:49:48

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

(python docs ) 'open' no tiene que ser añadido (es el 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.

 30
Author: DrBloodmoney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-31 02:16:29

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

 28
Author: dF.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-12 14:47:09
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])
 21
Author: nosklo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-16 19:33:55

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

Tenga en cuenta que en algunas plataformas, tratando de abrir un nombre de archivo función, puede funcionar e iniciar el sistema operativo asociado programa. 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")

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

 16
Author: etuardu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-15 17:19:04

Start no admite nombres de ruta largos ni espacios en blanco. Tienes que convertirlo a rutas compatibles con 8.3.

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 tiene que existir para poder trabajar con la llamada API.

 4
Author: bFloch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-05 09:22:42

Si quieres ir por el camino 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 programa cmd.exe. Esto funciona:

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

Pero solo si no hay espacios en el FILE_NAME.

Mientras que subprocess.call method en cita los parámetros correctamente, el comando start tiene una sintaxis bastante extraña, donde:

start notes.txt

Hace otra cosa 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 de arriba.

 4
Author: Tomas Sedovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-16 09:59:54

Llego bastante tarde al lote, pero aquí hay una solución utilizando 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 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. Leer el ShellExecute API docs para más información.

 1
Author: George,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-31 14:13:34

Os.startfile (path, 'open') bajo windows es bueno porque cuando existen espacios en el directorio, os.system ('start', path_name) no puede abrir la aplicación correctamente y cuando el i18n existe en el directorio, os.el sistema necesita cambiar el unicode al códec de la consola en Windows.

 1
Author: BearPy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-22 18:32:40

En mac os se puede llamar'open'

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

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

 0
Author: lcvinny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-12 06:34:06

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

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-03 21:46:36

En Windows 8.1, a continuación han trabajado mientras que otras formas dadas con subprocess.call falla 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))
 0
Author: Ch.Idea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-21 15:41:48