Мне нужно иметь возможность открывать документ с помощью приложения по умолчанию в Windows и Mac OS. По сути, я хочу сделать то же самое, что происходит, когда вы дважды щелкаете значок документа в проводнике или Finder. Как лучше всего это сделать в Python?
126
Ответы:
open
иstart
являются для этого средствами интерпретатора команд для Mac OS / X и Windows соответственно.Чтобы вызвать их из Python, вы можете использовать
subprocess
модуль илиos.system()
.Вот соображения относительно того, какой пакет использовать:
Вы можете позвонить им через
os.system
, что работает, но ...Экранирование:
os.system
работает только с именами файлов, в которых нет пробелов или других метасимволов оболочки в имени пути (напримерA:\abc\def\a.txt
), иначе их нужно экранировать. Естьshlex.quote
для Unix-подобных систем, но ничего стандартного для Windows. Возможно, посмотрите также python, windows: разбор командных строк с помощью shlexos.system("open " + shlex.quote(filename))
os.system("start " + filename)
куда, собственно говоряfilename
, тоже нужно убежать.Вы также можете вызвать их через
subprocess
модуль, но ...Для Python 2.7 и новее просто используйте
В Python 3.5+ вы можете эквивалентно использовать немного более сложный, но также несколько более универсальный
Если вам необходимо обеспечить полную совместимость с Python 2.4, вы можете использовать
subprocess.call()
и реализовать свою собственную проверку ошибок:Итак, каковы преимущества использования
subprocess
?'filename ; rm -rf /'
проблеме «но вы можете печатать », и если имя файла может быть повреждено, использованиеsubprocess.call
дает нам небольшую дополнительную защиту.retcode
в любом случае мы все еще зависим от них; но поведение явного вызова исключения в случае ошибки, безусловно, поможет вам заметить сбой (хотя в некоторых сценариях обратная трассировка может оказаться не более полезной, чем простое игнорирование ошибки).На возражение «Но
subprocess
предпочтительнее». Однакоos.system()
он не является устаревшим, и в некотором смысле это самый простой инструмент для этой конкретной работы. Вывод: использованиеos.system()
- тоже правильный ответ.Заметное недостатком является то , что Windows ,
start
команда требует , чтобы передать вshell=True
который сводит на нет большую часть преимуществ использованияsubprocess
.источник
filename
появляется форма, это прекрасный пример того, почему os.system () небезопасен и плох. подпроцесс лучше.os.system()
заключается в том, что он использует оболочку (и вы не выполняете здесь экранирование оболочки, поэтому плохие вещи будут происходить с совершенно допустимыми именами файлов, которые содержат метасимволы оболочки). Причина, по которойsubprocess.call()
это предпочтительнее, заключается в том, что у вас есть возможность обойти оболочку с помощьюsubprocess.call(["open", filename])
. Это работает для всех допустимых имен файлов и не представляет уязвимости внедрения оболочки даже для ненадежных имен файлов.Используйте
subprocess
модуль, доступный в Python 2.4+,os.system()
поэтому вам не нужно иметь дело с экранированием оболочки.Двойные скобки нужны потому, что
subprocess.call()
в качестве первого аргумента требуется последовательность, поэтому мы используем здесь кортеж. В системах Linux с Gnome также естьgnome-open
команда, которая делает то же самое, ноxdg-open
является стандартом Free Desktop Foundation и работает в средах рабочего стола Linux.источник
xdg-open
- linux.die.net/man/1/xdg-openxdg-open test.py
и он открыл для меня диалог загрузки firefox. В чем дело? Я использую manjaro linux.xdg-open
конфигурация запуталась, но это не совсем то, что мы можем устранить в комментариях. Может быть, см. Unix.stackexchange.com/questions/36380/…Я предпочитаю:
Обратите внимание, что этот модуль поддерживает имена файлов, в папках и файлах которых есть пробелы, например
( python docs ) 'open' добавлять не нужно (это значение по умолчанию). В документах специально упоминается, что это похоже на двойной щелчок по значку файла в проводнике Windows.
Это решение только для окон.
источник
startfile
функция даже не существует, а это означает, что пользователи получат сбивающее с толку сообщение об ошибке об отсутствующей функции. Вы можете проверить платформу, чтобы избежать этого.Просто для полноты (это не было вопросом), xdg-open сделает то же самое в Linux.
источник
источник
Если вам нужно использовать эвристический метод, вы можете подумать
webbrowser
.Это стандартная библиотека, и, несмотря на название, она также пытается открывать файлы:
Я попробовал этот код, и он отлично работал в Windows 7 и Ubuntu Natty:
Этот код также отлично работает в Windows XP Professional с использованием Internet Explorer 8.
источник
open location
там, что должно работать, если вы укажете путь как действительный URL-адрес.import webbrowser webbrowser.open("file:///Users/nameGoesHere/Desktop/folder/file.py")
Если вы хотите пойти своим
subprocess.call()
путем, в Windows это должно выглядеть так:Вы не можете просто использовать:
потому что
start
это не исполняемый файл, а командаcmd.exe
программы. Это работает:но только если в FILE_NAME нет пробелов.
Хотя
subprocess.call
методenправильно цитирует параметры,start
команда имеет довольно странный синтаксис, где:делает что-то еще, кроме:
Первая строка в кавычках должна устанавливать заголовок окна. Чтобы он работал с пробелами, нам нужно сделать:
что и делает код сверху.
источник
Start не поддерживает длинные имена путей и пробелы. Вы должны преобразовать его в 8,3-совместимые пути.
Файл должен существовать для работы с вызовом API.
источник
start "Title" "C:\long path to\file.avi"
Я довольно опаздываю, но вот решение, использующее windows api. Это всегда открывает связанное приложение.
Множество магических констант. Первый ноль - это hwnd текущей программы. Может быть нулевым. Два других нуля - это необязательные параметры (параметры и каталог). 5 == SW_SHOW, он указывает, как запускать приложение. Прочтите документацию по API ShellExecute для получения дополнительной информации.
источник
os.startfile(file)
?в mac os вы можете назвать "открыть"
это откроет файл с помощью TextEdit или любого другого приложения, установленного по умолчанию для этого типа файла
источник
Если вы хотите указать приложение для открытия файла в Mac OS X, используйте это:
os.system("open -a [app name] [file name]")
источник
В Windows 8.1 ниже работали, в то время как другие способы с
subprocess.call
ошибками с path имеют пробелы.Используя этот и другие ответы ранее, вот встроенный код, который работает на нескольких платформах.
источник
os.startfile(path, 'open')
под Windows это хорошо, потому что, когда в каталоге существуют пробелы,os.system('start', path_name)
приложение не может правильно открыть, а когда в каталоге существует i18n,os.system
необходимо изменить Unicode на кодек консоли в Windows.источник