J'ai besoin de pouvoir ouvrir un document en utilisant son application par défaut sous Windows et Mac OS. Fondamentalement, je veux faire la même chose que lorsque vous double-cliquez sur l'icône du document dans l'Explorateur ou le Finder. Quelle est la meilleure façon de faire cela en Python?
126
Réponses:
open
etstart
sont des choses d'interpréteur de commandes pour Mac OS / X et Windows respectivement, pour ce faire.Pour les appeler depuis Python, vous pouvez utiliser le
subprocess
module ouos.system()
.Voici quelques considérations sur le package à utiliser:
Vous pouvez les appeler via
os.system
, ce qui fonctionne, mais ...Escaping:
os.system
fonctionne uniquement avec les noms de fichiers qui n'ont pas d'espaces ou d'autres métacaractères shell dans le chemin d'accès (par exempleA:\abc\def\a.txt
), sinon ceux-ci doivent être échappés. Il y en ashlex.quote
pour les systèmes de type Unix, mais rien de vraiment standard pour Windows. Peut-être voir aussi python, windows: analyse des lignes de commande avec shlexos.system("open " + shlex.quote(filename))
os.system("start " + filename)
là où proprement ditfilename
doit être échappé aussi.Vous pouvez également les appeler via le
subprocess
module, mais ...Pour Python 2.7 et plus récent, utilisez simplement
Dans Python 3.5+, vous pouvez utiliser de manière équivalente le légèrement plus complexe mais aussi un peu plus polyvalent
Si vous avez besoin d'être compatible jusqu'à Python 2.4, vous pouvez utiliser
subprocess.call()
et implémenter votre propre vérification d'erreur:Maintenant, quels sont les avantages de l'utilisation
subprocess
?'filename ; rm -rf /'
problème inhérent "mais vous pouvez taper ", et si le nom de fichier peut être corrompu, utilisersubprocess.call
nous donne peu de protection supplémentaire.retcode
dans les deux cas; mais le comportement pour déclencher explicitement une exception en cas d'erreur vous aidera certainement à remarquer s'il y a un échec (bien que dans certains scénarios, un retraçage ne soit pas du tout plus utile que d'ignorer simplement l'erreur).À l'objection «mais
subprocess
est préféré». Cependant,os.system()
n'est pas obsolète, et c'est en quelque sorte l'outil le plus simple pour ce travail particulier. Conclusion: utiliseros.system()
est donc aussi une bonne réponse.Un inconvénient majeur est que la
start
commande Windows vous oblige à passershell=True
ce qui annule la plupart des avantages de l'utilisationsubprocess
.la source
filename
vient la forme, c'est un exemple parfait de pourquoi os.system () n'est pas sécurisé et est mauvais. le sous-processus est meilleur.os.system()
est qu'il utilise le shell (et vous ne faites aucun shell qui s'échappe ici, donc de mauvaises choses se produiront pour des noms de fichiers parfaitement valides qui contiennent des méta-caractères du shell). La raison pour laquellesubprocess.call()
est préféré est que vous avez la possibilité de contourner le shell en utilisantsubprocess.call(["open", filename])
. Cela fonctionne pour tous les noms de fichiers valides et n'introduit pas de vulnérabilité d'injection shell, même pour les noms de fichiers non approuvés.Utilisez le
subprocess
module disponible sur Python 2.4+, nonos.system()
, pour ne pas avoir à gérer l'échappement du shell.Les doubles parenthèses sont parce que
subprocess.call()
veut une séquence comme premier argument, nous utilisons donc un tuple ici. Sur les systèmes Linux avec Gnome, il existe également unegnome-open
commande qui fait la même chose, mais quixdg-open
est le standard de Free Desktop Foundation et fonctionne dans les environnements de bureau Linux.la source
xdg-open
- linux.die.net/man/1/xdg-openxdg-open test.py
et il a ouvert la boîte de dialogue de téléchargement de Firefox pour moi. Qu'est-ce qui ne va pas? Je suis sur manjaro linux.xdg-open
configuration est confuse, mais ce n'est pas vraiment quelque chose que nous pouvons résoudre dans un commentaire. Peut-être voir unix.stackexchange.com/questions/36380/…Je préfère:
Notez que ce module prend en charge les noms de fichiers qui ont des espaces dans leurs dossiers et fichiers, par exemple
( python docs ) 'open' n'a pas besoin d'être ajouté (c'est la valeur par défaut). La documentation mentionne spécifiquement que cela revient à double-cliquer sur l'icône d'un fichier dans l'Explorateur Windows.
Cette solution concerne uniquement Windows.
la source
startfile
fonction n'existe même pas, ce qui signifie que les utilisateurs recevront un message d'erreur déroutant à propos d'une fonction manquante. Vous voudrez peut-être vérifier la plate-forme pour éviter cela.Juste pour être complet (ce n'était pas dans la question), xdg-open fera de même sous Linux.
la source
la source
Si vous devez utiliser une méthode heuristique, vous pouvez envisager
webbrowser
.C'est une bibliothèque standard et malgré son nom, elle essaierait également d'ouvrir des fichiers:
J'ai essayé ce code et cela a bien fonctionné sous Windows 7 et Ubuntu Natty:
Ce code fonctionne également correctement dans Windows XP Professionnel, en utilisant Internet Explorer 8.
la source
open location
là-bas qui devrait fonctionner si vous donnez le chemin comme une URL valide.import webbrowser webbrowser.open("file:///Users/nameGoesHere/Desktop/folder/file.py")
Si vous voulez suivre le
subprocess.call()
chemin, cela devrait ressembler à ceci sous Windows:Vous ne pouvez pas simplement utiliser:
car ce
start
n'est pas un exécutable mais une commande ducmd.exe
programme. Cela marche:mais uniquement s'il n'y a pas d'espaces dans le FILE_NAME.
Alors que la
subprocess.call
méthodeencite correctement les paramètres, lastart
commande a une syntaxe plutôt étrange, où:fait autre chose que:
La première chaîne entre guillemets doit définir le titre de la fenêtre. Pour le faire fonctionner avec les espaces, nous devons faire:
c'est ce que fait le code en haut.
la source
Start ne prend pas en charge les noms de chemin longs et les espaces blancs. Vous devez le convertir en chemins compatibles 8.3.
Le fichier doit exister pour fonctionner avec l'appel d'API.
la source
start "Title" "C:\long path to\file.avi"
Je suis assez tard dans le lot, mais voici une solution utilisant l'API Windows. Cela ouvre toujours l'application associée.
Beaucoup de constantes magiques. Le premier zéro est le hwnd du programme en cours. Peut être zéro. Les deux autres zéros sont des paramètres optionnels (paramètres et répertoire). 5 == SW_SHOW, il spécifie comment exécuter l'application. Lisez la documentation de l'API ShellExecute pour plus d'informations.
la source
os.startfile(file)
?sur mac os, vous pouvez appeler «ouvert»
cela ouvrirait le fichier avec TextEdit, ou n'importe quelle application définie par défaut pour ce type de fichier
la source
Si vous souhaitez spécifier l'application avec laquelle ouvrir le fichier sous Mac OS X, utilisez ceci:
os.system("open -a [app name] [file name]")
la source
Sur Windows 8.1, ci-dessous ont fonctionné alors que d'autres méthodes données avec
subprocess.call
échec avec chemin contiennent des espaces.En utilisant ceci et les réponses d'autres auparavant, voici un code en ligne qui fonctionne sur plusieurs plates-formes.
la source
os.startfile(path, 'open')
sous Windows, c'est bien car lorsque des espaces existent dans le répertoire,os.system('start', path_name)
ne peut pas ouvrir l'application correctement et lorsque l'i18n existe dans le répertoire, ilos.system
faut changer l'unicode en codec de la console sous Windows.la source