Open document with default OS application in Python, both in Windows and Mac OS
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------
Take control of your privacy with Proton's trusted, Swiss-based, secure services.
Choose what you need and safeguard your digital life:
Mail: https://go.getproton.me/SH1CU
VPN: https://go.getproton.me/SH1DI
Password Manager: https://go.getproton.me/SH1DJ
Drive: https://go.getproton.me/SH1CT
Music by Eric Matyas
https://www.soundimage.org
Track title: Hypnotic Puzzle2
--
Chapters
00:00 Open Document With Default Os Application In Python, Both In Windows And Mac Os
00:25 Accepted Answer Score 103
03:13 Answer 2 Score 62
03:40 Answer 3 Score 43
03:49 Answer 4 Score 226
04:25 Thank you
--
Full question
https://stackoverflow.com/questions/4345...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #windows #macos
#avk47
ANSWER 1
Score 226
Use the subprocess module available on Python 2.4+, not os.system(), so you don't have to deal with shell escaping.
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))
The double parentheses are because subprocess.call() wants a sequence as its first argument, so we're using a tuple here. On Linux systems with Gnome there is also a gnome-open command that does the same thing, but xdg-open is the Free Desktop Foundation standard and works across Linux desktop environments.
ACCEPTED ANSWER
Score 103
open and start are command-interpreter things for Mac OS/X and Windows respectively, to do this.
To call them from Python, you can either use subprocess module or os.system().
Here are considerations on which package to use:
You can call them via
os.system, which works, but...Escaping:
os.systemonly works with filenames that don't have any spaces or other shell metacharacters in the pathname (e.g.A:\abc\def\a.txt), or else these need to be escaped. There isshlex.quotefor Unix-like systems, but nothing really standard for Windows. Maybe see also python, windows : parsing command lines with shlex- MacOS/X:
os.system("open " + shlex.quote(filename)) - Windows:
os.system("start " + filename)where properly speakingfilenameshould be escaped, too.
- MacOS/X:
You can also call them via
subprocessmodule, but...For Python 2.7 and newer, simply use
subprocess.check_call(['open', filename])In Python 3.5+ you can equivalently use the slightly more complex but also somewhat more versatile
subprocess.run(['open', filename], check=True)If you need to be compatible all the way back to Python 2.4, you can use
subprocess.call()and implement your own error checking: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:", eNow, what are the advantages of using
subprocess?- Security: In theory, this is more secure, but in fact we're needing to execute a command line one way or the other; in either environment, we need the environment and services to interpret, get paths, and so forth. In neither case are we executing arbitrary text, so it doesn't have an inherent "but you can type
'filename ; rm -rf /'" problem, and if the file name can be corrupted, usingsubprocess.callgives us little additional protection. - Error handling: It doesn't actually give us any more error detection, we're still depending on the
retcodein either case; but the behavior to explicitly raise an exception in the case of an error will certainly help you notice if there is a failure (though in some scenarios, a traceback might not at all be more helpful than simply ignoring the error). - Spawns a (non-blocking) subprocess: We don't need to wait for the child process, since we're by problem statement starting a separate process.
To the objection "But
subprocessis preferred." However,os.system()is not deprecated, and it's in some sense the simplest tool for this particular job. Conclusion: usingos.system()is therefore also a correct answer.A marked disadvantage is that the Windows
startcommand requires you to pass inshell=Truewhich negates most of the benefits of usingsubprocess.- Security: In theory, this is more secure, but in fact we're needing to execute a command line one way or the other; in either environment, we need the environment and services to interpret, get paths, and so forth. In neither case are we executing arbitrary text, so it doesn't have an inherent "but you can type
ANSWER 3
Score 62
I prefer:
os.startfile(path, 'open')
Note that this module supports filenames that have spaces in their folders and files e.g.
A:\abc\folder with spaces\file with-spaces.txt
(python docs) 'open' does not have to be added (it is the default). The docs specifically mention that this is like double-clicking on a file's icon in Windows Explorer.
This solution is windows only.
ANSWER 4
Score 43
Just for completeness (it wasn't in the question), xdg-open will do the same on Linux.