How to open external programs in Python

后端 未结 1 741
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-05 08:53

Duplicate edit: no, i did that but it doesnt want to launch firefox. I am making a cortana/siri assistant thing, and I want it to lets say open a web browser when I say some

相关标签:
1条回答
  • 2020-12-05 09:22

    The short answer is that os.system doesn't know where to find firefox.exe.

    A possible solution would be to use the full path. And it is recommended to use the subprocess module:

    import subprocess
    
    subprocess.call(['C:\Program Files\Mozilla Firefox\\firefox.exe'])
    

    Mind the \\ before the firefox.exe! If you'd use \f, Python would interpret this as a formfeed:

    >>> print('C:\Program Files\Mozilla Firefox\firefox.exe')
    C:\Program Files\Mozilla Firefox
                                    irefox.exe
    

    And of course that path doesn't exist. :-)

    So either escape the backslash or use a raw string:

    >>> print('C:\Program Files\Mozilla Firefox\\firefox.exe')
    C:\Program Files\Mozilla Firefox\firefox.exe
    >>> print(r'C:\Program Files\Mozilla Firefox\firefox.exe')
    C:\Program Files\Mozilla Firefox\firefox.exe
    

    Note that using os.system or subprocess.call will stop the current application until the program that is started finishes. So you might want to use subprocess.Popen instead. That will launch the external program and then continue the script.

    subprocess.Popen(['C:\Program Files\Mozilla Firefox\\firefox.exe', '-new-tab'])
    

    This will open firefox (or create a new tab in a running instance).


    A more complete example is my open utility I publish via github. This uses regular expressions to match file extensions to programs to open those files with. Then it uses subprocess.Popen to open those files in an appropriate program. For reference I'm adding the complete code for the current version below.

    Note that this program was written with UNIX-like operating systems in mind. On ms-windows you could probably get an application for a filetype from the registry.

    """Opens the file(s) given on the command line in the appropriate program.
    Some of the programs are X11 programs."""
    
    from os.path import isdir, isfile
    from re import search, IGNORECASE
    from subprocess import Popen, check_output, CalledProcessError
    from sys import argv
    import argparse
    import logging
    
    __version__ = '1.3.0'
    
    # You should adjust the programs called to suit your preferences.
    filetypes = {
        '\.(pdf|epub)$': ['mupdf'],
        '\.html$': ['chrome', '--incognito'],
        '\.xcf$': ['gimp'],
        '\.e?ps$': ['gv'],
        '\.(jpe?g|png|gif|tiff?|p[abgp]m|svg)$': ['gpicview'],
        '\.(pax|cpio|zip|jar|ar|xar|rpm|7z)$': ['tar', 'tf'],
        '\.(tar\.|t)(z|gz|bz2?|xz)$': ['tar', 'tf'],
        '\.(mp4|mkv|avi|flv|mpg|movi?|m4v|webm)$': ['mpv']
    }
    othertypes = {'dir': ['rox'], 'txt': ['gvim', '--nofork']}
    
    
    def main(argv):
        """Entry point for this script.
    
        Arguments:
            argv: command line arguments; list of strings.
        """
        if argv[0].endswith(('open', 'open.py')):
            del argv[0]
        opts = argparse.ArgumentParser(prog='open', description=__doc__)
        opts.add_argument('-v', '--version', action='version',
                          version=__version__)
        opts.add_argument('-a', '--application', help='application to use')
        opts.add_argument('--log', default='warning',
                          choices=['debug', 'info', 'warning', 'error'],
                          help="logging level (defaults to 'warning')")
        opts.add_argument("files", metavar='file', nargs='*',
                          help="one or more files to process")
        args = opts.parse_args(argv)
        logging.basicConfig(level=getattr(logging, args.log.upper(), None),
                            format='%(levelname)s: %(message)s')
        logging.info('command line arguments = {}'.format(argv))
        logging.info('parsed arguments = {}'.format(args))
        fail = "opening '{}' failed: {}"
        for nm in args.files:
            logging.info("Trying '{}'".format(nm))
            if not args.application:
                if isdir(nm):
                    cmds = othertypes['dir'] + [nm]
                elif isfile(nm):
                    cmds = matchfile(filetypes, othertypes, nm)
                else:
                    cmds = None
            else:
                cmds = [args.application, nm]
            if not cmds:
                logging.warning("do not know how to open '{}'".format(nm))
                continue
            try:
                Popen(cmds)
            except OSError as e:
                logging.error(fail.format(nm, e))
        else:  # No files named
            if args.application:
                try:
                    Popen([args.application])
                except OSError as e:
                    logging.error(fail.format(args.application, e))
    
    
    def matchfile(fdict, odict, fname):
        """For the given filename, returns the matching program. It uses the `file`
        utility commonly available on UNIX.
    
        Arguments:
            fdict: Handlers for files. A dictionary of regex:(commands)
                representing the file type and the action that is to be taken for
                opening one.
            odict: Handlers for other types. A dictionary of str:(arguments).
            fname: A string containing the name of the file to be opened.
    
        Returns: A list of commands for subprocess.Popen.
        """
        for k, v in fdict.items():
            if search(k, fname, IGNORECASE) is not None:
                return v + [fname]
        try:
            if b'text' in check_output(['file', fname]):
                return odict['txt'] + [fname]
        except CalledProcessError:
            logging.warning("the command 'file {}' failed.".format(fname))
            return None
    
    
    if __name__ == '__main__':
        main(argv)
    
    0 讨论(0)
提交回复
热议问题