Muszę móc otworzyć dokument przy użyciu domyślnej aplikacji w systemie Windows i Mac OS. Zasadniczo chcę zrobić to samo, co dzieje się po dwukrotnym kliknięciu ikony dokumentu w Eksploratorze lub Finderze. Jaki jest najlepszy sposób na zrobienie tego w Pythonie?
126
Odpowiedzi:
open
istart
są interpreterami poleceń odpowiednio dla Mac OS / X i Windows, aby to zrobić.Aby wywołać je z Pythona, możesz użyć
subprocess
module lubos.system()
.Oto uwagi dotyczące tego, którego pakietu użyć:
Możesz do nich zadzwonić
os.system
, co działa, ale ...Escaping:
os.system
działa tylko z nazwami plików, które nie mają żadnych spacji ani innych metaznaków powłoki w nazwie ścieżki (np.A:\abc\def\a.txt
), Albo wymagają one zmiany znaczenia. Jestshlex.quote
dla systemów typu Unix, ale nie ma nic standardowego dla Windows. Może zobacz także python, windows: parsing wiersza poleceń za pomocą shlexos.system("open " + shlex.quote(filename))
os.system("start " + filename)
tam, gdziefilename
należy uciec od prawidłowego mówienia .Możesz też zadzwonić do nich przez
subprocess
moduł, ale ...W przypadku Pythona 2.7 i nowszych po prostu użyj
W Pythonie 3.5+ możesz równoważnie użyć nieco bardziej złożonego, ale też nieco bardziej wszechstronnego
Jeśli chcesz zachować zgodność aż do Pythona 2.4, możesz użyć
subprocess.call()
i zaimplementować własne sprawdzanie błędów:Jakie są zalety używania
subprocess
?'filename ; rm -rf /'
problemu „ale możesz wpisać ”, a jeśli nazwa pliku może być uszkodzona, użycie niesubprocess.call
daje nam dodatkowej ochrony.retcode
obu przypadkach; ale zachowanie polegające na jawnym zgłaszaniu wyjątku w przypadku błędu z pewnością pomoże ci zauważyć, jeśli wystąpi awaria (chociaż w niektórych scenariuszach śledzenie może wcale nie być bardziej pomocne niż po prostu zignorowanie błędu).Na zastrzeżenie „Ale
subprocess
jest preferowane”. Jednakos.system()
nie jest przestarzałe i jest w pewnym sensie najprostszym narzędziem do tego konkretnego zadania. Wniosek: używanieos.system()
jest zatem również poprawną odpowiedzią.Znaczącą wadą jest to, że
start
polecenie systemu Windows wymaga przejścia,shell=True
co neguje większość korzyści wynikających z używaniasubprocess
.źródło
filename
formy, jest to doskonały przykład tego, dlaczego os.system () jest niepewne i złe. podproces jest lepszy.os.system()
polega na tym, że używa powłoki (i nie wykonujesz tutaj żadnej ucieczki powłoki, więc złe rzeczy będą się zdarzać w przypadku doskonale poprawnych nazw plików, które zawierają meta-znaki powłoki). Powodem, dla któregosubprocess.call()
jest to preferowane jest to, że masz możliwość ominięcia powłoki za pomocąsubprocess.call(["open", filename])
. Działa to dla wszystkich prawidłowych nazw plików i nie wprowadza luki umożliwiającej wstrzyknięcie powłoki nawet w przypadku niezaufanych nazw plików.Nie używaj
subprocess
modułu dostępnego w Pythonie 2.4+,os.system()
więc nie musisz zajmować się ucieczką z powłoki.Podwójne nawiasy są spowodowane
subprocess.call()
tym, że jako pierwszy argument potrzebny jest ciąg, więc używamy tutaj krotki. W systemach Linux z Gnome istnieje równieżgnome-open
polecenie, które robi to samo, alexdg-open
jest standardem Free Desktop Foundation i działa w środowiskach Linux.źródło
xdg-open
- linux.die.net/man/1/xdg-openxdg-open test.py
i otworzyło się dla mnie okno dialogowe pobierania programu Firefox. Co jest nie tak? Jestem na Linuksie Manjaro.xdg-open
to, że twoja konfiguracja jest zdezorientowana, ale nie jest to coś, co możemy rozwiązać w komentarzu. Może zobacz unix.stackexchange.com/questions/36380/ ...Wolę:
Zauważ, że ten moduł obsługuje nazwy plików, które mają spacje w swoich folderach i plikach, np
( Python docs ) „open” nie musi być dodawane (jest to ustawienie domyślne). Dokumenty wyraźnie wspominają, że jest to podobne do dwukrotnego kliknięcia ikony pliku w Eksploratorze Windows.
To rozwiązanie dotyczy tylko okien.
źródło
startfile
funkcja nawet nie istnieje, co oznacza, że użytkownicy otrzymają mylący komunikat o błędzie dotyczący brakującej funkcji. Możesz sprawdzić platformę, aby tego uniknąć.Dla kompletności (nie było tego w pytaniu), xdg-open zrobi to samo na Linuksie.
źródło
źródło
Jeśli musisz użyć metody heurystycznej, możesz rozważyć
webbrowser
.Jest to standardowa biblioteka i pomimo swojej nazwy próbuje też otwierać pliki:
Wypróbowałem ten kod i działał dobrze w Windows 7 i Ubuntu Natty:
Ten kod działa również dobrze w systemie Windows XP Professional, przy użyciu przeglądarki Internet Explorer 8.
źródło
open location
tam, co powinno działać, jeśli podasz ścieżkę jako prawidłowy adres URL.import webbrowser webbrowser.open("file:///Users/nameGoesHere/Desktop/folder/file.py")
Jeśli chcesz iść
subprocess.call()
drogą, powinno to wyglądać tak w systemie Windows:Nie możesz po prostu użyć:
ponieważ
start
nie jest plikiem wykonywalnym, ale poleceniemcmd.exe
programu. To działa:ale tylko wtedy, gdy w FILE_NAME nie ma spacji.
Chociaż
subprocess.call
metodaenpoprawnie cytuje parametry,start
polecenie ma dość dziwną składnię, gdzie:robi coś innego niż:
Pierwszy cytowany ciąg powinien określać tytuł okna. Aby działało z przestrzeniami, musimy:
co robi kod na górze.
źródło
Start nie obsługuje długich nazw ścieżek i spacji. Musisz go przekonwertować na ścieżki kompatybilne z 8.3.
Plik musi istnieć, aby działał z wywołaniem API.
źródło
start "Title" "C:\long path to\file.avi"
Spóźniłem się na wiele, ale oto rozwiązanie wykorzystujące interfejs API systemu Windows. Spowoduje to zawsze otwarcie skojarzonej aplikacji.
Wiele magicznych stałych. Pierwsze zero to hwnd bieżącego programu. Może wynosić zero. Pozostałe dwa zera to parametry opcjonalne (parametry i katalog). 5 == SW_SHOW, określa, jak uruchomić aplikację. Przeczytaj dokumentację ShellExecute API, aby uzyskać więcej informacji.
źródło
os.startfile(file)
?w systemie Mac OS możesz nazwać „otwórz”
spowoduje to otwarcie pliku za pomocą TextEdit lub dowolnej aplikacji ustawionej jako domyślna dla tego typu pliku
źródło
Jeśli chcesz określić aplikację do otwierania pliku w systemie Mac OS X, użyj tego:
os.system("open -a [app name] [file name]")
źródło
W systemie Windows 8.1 poniżej działały, podczas gdy inne podane sposoby z
subprocess.call
błędami ze ścieżką mają spacje.Korzystając wcześniej z tego i innych odpowiedzi, oto kod wbudowany, który działa na wielu platformach.
źródło
os.startfile(path, 'open')
pod Windows jest dobre, ponieważ gdy istnieją spacje w katalogu,os.system('start', path_name)
nie można poprawnie otworzyć aplikacji, a gdy i18n istnieje w katalogu,os.system
musi zmienić unicode na kodek konsoli w systemie Windows.źródło