Windows 및 Mac OS 모두에서 Python의 기본 OS 응용 프로그램으로 문서 열기
Windows 및 Mac OS에서 기본 응용 프로그램을 사용하여 문서를 열 수 있어야합니다. 기본적으로 탐색기 또는 Finder에서 문서 아이콘을 두 번 클릭 할 때 발생하는 것과 동일한 작업을 수행하려고합니다. 파이썬에서 이것을 수행하는 가장 좋은 방법은 무엇입니까?
open그리고 start이 일을 맥 OS / X 및 Windows 명령 인터프리터 가지 각각이다.
파이썬에서 호출하려면 subprocessmodule 또는을 사용할 수 있습니다 os.system().
사용할 패키지에 대한 고려 사항은 다음과 같습니다.
당신은 그들을 통해 전화 할 수 있습니다
os.system.이스케이프 :
os.system경로 이름에 공백이나 다른 셸 메타 문자가없는 파일 이름 (예 :) 에서만 작동A:\abc\def\a.txt하거나 이스케이프해야합니다. 이shlex.quote유닉스 시스템,하지만 윈도우 아무것도 정말 표준입니다. python, windows 참조 : shlex로 명령 줄 구문 분석- 맥 OS X:
os.system("open " + shlex.quote(filename)) - Windows :
os.system("start " + filename)제대로 말하기도filename피해야합니다.
- 맥 OS X:
subprocess모듈을 통해 호출 할 수도 있지만 ...Python 2.7 이상에서는 간단히
subprocess.check_call(['open', filename])Python 3.5 이상에서는 약간 더 복잡하지만 좀 더 다목적으로 사용할 수 있습니다
subprocess.run(['open', filename], check=True)Python 2.4와 완벽하게 호환되어야하는 경우
subprocess.call()자체 오류 검사를 사용 하고 구현할 수 있습니다.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:", e이제 사용하면 어떤 이점이
subprocess있습니까?- 보안 : 이론 상으로는이 방법이 더 안전하지만 실제로는 명령 줄을 실행해야합니다. 어느 환경에서나 해석하고 길을 찾는 등의 환경과 서비스가 필요합니다. 어느 경우 우리가 그것을 고유이 없습니다 "하지만 당신은 입력 할 수 있습니다, 임의의 텍스트를 실행하다
'filename ; rm -rf /'"문제를, 그리고 경우 파일 이름이 손상 될 수 있으며, 사용하는 것은subprocess.call우리에게 약간의 추가적인 보호 기능을 제공합니다. - 오류 처리 : 실제로 더 이상 오류 감지를 제공하지는 않지만 여전히
retcode두 경우 모두 에 따라 다릅니다 . 그러나 오류가 발생했을 때 명시 적으로 예외를 발생시키는 동작은 오류가 발생했는지 확인하는 데 도움이됩니다 (일부 시나리오에서는 단순히 오류를 무시하는 것보다 트레이스 백이 더 도움이되지 않을 수 있습니다). - (차단되지 않은) 서브 프로세스를 생성합니다 : 우리는 별도의 프로세스를 시작하는 문제에 의해 자식 프로세스를 기다릴 필요가 없습니다.
이의 제기 "하지만
subprocess바람직하다." 그러나os.system()더 이상 사용되지 않으며 어떤 의미에서는이 특정 작업을위한 가장 간단한 도구입니다. 결론 : 사용os.system()하는 것도 정답입니다.표시 단점은 윈도우이다
start명령은 필요 에 전달할 수shell=True있는 사용의 이점의 대부분을 부정subprocess.- 보안 : 이론 상으로는이 방법이 더 안전하지만 실제로는 명령 줄을 실행해야합니다. 어느 환경에서나 해석하고 길을 찾는 등의 환경과 서비스가 필요합니다. 어느 경우 우리가 그것을 고유이 없습니다 "하지만 당신은 입력 할 수 있습니다, 임의의 텍스트를 실행하다
subprocessPython 2.4 이상에서 사용할 수 있는 모듈을 사용하십시오. os.system()따라서 쉘 이스케이프 처리를 할 필요가 없습니다.
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))
이중 괄호는 subprocess.call()시퀀스를 첫 번째 인수로 원 하기 때문에 여기에서 튜플을 사용하고 있습니다. Gnome을 사용하는 Linux 시스템 gnome-open에는 동일한 작업을 수행 하는 명령 도 있지만 xdg-openFree Desktop Foundation 표준이며 Linux 데스크탑 환경에서 작동합니다.
나는 선호한다:
os.startfile(path, 'open')
이 모듈은 폴더와 파일에 공백이있는 파일 이름을 지원합니다.
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.
Just for completeness (it wasn't in the question), xdg-open will do the same on Linux.
import os
import subprocess
def click_on_file(filename):
'''Open document with default application in Python.'''
try:
os.startfile(filename)
except AttributeError:
subprocess.call(['open', filename])
If you have to use an heuristic method, you may consider webbrowser.
It's standard library and despite of its name it would also try to open files:
Note that on some platforms, trying to open a filename using this function, may work and start the operating system’s associated program. However, this is neither supported nor portable. (Reference)
I tried this code and it worked fine in Windows 7 and Ubuntu Natty:
import webbrowser
webbrowser.open("path_to_file")
This code also works fine in Windows XP Professional, using Internet Explorer 8.
Start does not support long path names and white spaces. You have to convert it to 8.3 compatible paths.
import subprocess
import win32api
filename = "C:\\Documents and Settings\\user\\Desktop\file.avi"
filename_short = win32api.GetShortPathName(filename)
subprocess.Popen('start ' + filename_short, shell=True )
The file has to exist in order to work with the API call.
If you want to go the subprocess.call() way, it should look like this on Windows:
import subprocess
subprocess.call(('cmd', '/C', 'start', '', FILE_NAME))
You can't just use:
subprocess.call(('start', FILE_NAME))
because start is not an executable but a command of the cmd.exe program. This works:
subprocess.call(('cmd', '/C', 'start', FILE_NAME))
but only if there are no spaces in the FILE_NAME.
While subprocess.call method
en
quotes the parameters properly, the start command has a rather strange syntax, where:
start notes.txt
does something else than:
start "notes.txt"
The first quoted string should set the title of the window. To make it work with spaces, we have to do:
start "" "my notes.txt"
which is what the code on top does.
I am pretty late to the lot, but here is a solution using the windows api. This always opens the associated application.
import ctypes
shell32 = ctypes.windll.shell32
file = 'somedocument.doc'
shell32.ShellExecuteA(0,"open",file,0,0,5)
A lot of magic constants. The first zero is the hwnd of the current program. Can be zero. The other two zeros are optional parameters (parameters and directory). 5 == SW_SHOW, it specifies how to execute the app. Read the ShellExecute API docs for more info.
os.startfile(path, 'open') under windows is good because when spaces exist in the directory, os.system('start', path_name) can't open the app correct and when the i18n exist in the directory, os.system needs to change the unicode to the codec of the console in Windows.
on mac os you can call 'open'
import os
os.popen("open myfile.txt")
this would open the file with TextEdit, or whatever app is set as default for this filetype
If you want to specify the app to open the file with on Mac OS X, use this: os.system("open -a [app name] [file name]")
On windows 8.1, below have worked while other given ways with subprocess.call fails with path has spaces in it.
subprocess.call('cmd /c start "" "any file path with spaces"')
By utilizing this and other's answers before, here's an inline code which works on multiple platforms.
import sys, os, subprocess
subprocess.call(('cmd /c start "" "'+ filepath +'"') if os.name is 'nt' else ('open' if sys.platform.startswith('darwin') else 'xdg-open', filepath))
'Programing' 카테고리의 다른 글
| jQuery 및 CSS-표시 제거 / 추가 : 없음 (0) | 2020.07.28 |
|---|---|
| htaccess 액세스 제어 허용 원본 (0) | 2020.07.28 |
| PHP에서 서버 IP 주소를 식별하는 방법 (0) | 2020.07.28 |
| 파일 또는 어셈블리 Microsoft.SqlServer.management.sdk.sfc 버전 11.0.0.0을로드 할 수 없습니다 (0) | 2020.07.28 |
| Rails에서-개행을로 변환하는 rails 방법이 (0) | 2020.07.28 |