Windows 및 Mac OS에서 기본 응용 프로그램을 사용하여 문서를 열 수 있어야합니다. 기본적으로 Explorer 또는 Finder에서 문서 아이콘을 두 번 클릭 할 때 발생하는 것과 동일한 작업을 수행하고 싶습니다. 파이썬에서 이것을 수행하는 가장 좋은 방법은 무엇입니까?
답변
open
그리고 start
이 일을 맥 OS / X 및 Windows 명령 인터프리터 가지 각각이다.
Python에서 호출하려면 subprocess
module 또는 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
. - 보안 : 이론적으로는 더 안전하지만 실제로는 명령 줄을 어떤 방식 으로든 실행해야합니다. 어느 환경에서든 해석하고 경로를 얻는 등의 작업을 수행 할 환경과 서비스가 필요합니다. 어느 경우 우리가 그것을 고유이 없습니다 “하지만 당신은 입력 할 수 있습니다, 임의의 텍스트를 실행하다
답변
subprocess
Python 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-open
Free Desktop Foundation 표준이며 Linux 데스크톱 환경에서 작동 하는 명령 도 있습니다.
답변
나는 선호한다:
os.startfile(path, 'open')
이 모듈은 폴더와 파일에 공백이있는 파일 이름을 지원합니다.
A:\abc\folder with spaces\file with-spaces.txt
( python docs ) ‘open’은 추가 할 필요가 없습니다 (기본값). 문서에서는 Windows 탐색기에서 파일 아이콘을 두 번 클릭하는 것과 같음을 구체적으로 언급합니다.
이 솔루션은 Windows 전용입니다.
답변
완전성을 위해 (문제가 아님) xdg-open 은 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])
답변
휴리스틱 방법을 사용해야하는 경우를 고려할 수 있습니다 webbrowser
.
표준 라이브러리이며 이름에도 불구하고 파일을 열려고 시도합니다.
일부 플랫폼에서는이 기능을 사용하여 파일 이름을 열려고하면 작동하고 운영 체제 관련 프로그램이 시작될 수 있습니다. 그러나 이것은 지원되거나 이식 가능하지 않습니다. ( 참조 )
이 코드를 시도했지만 Windows 7 및 Ubuntu Natty에서 제대로 작동했습니다.
import webbrowser
webbrowser.open("path_to_file")
이 코드는 Internet Explorer 8을 사용하는 Windows XP Professional에서도 잘 작동합니다.
답변
계속 진행하려면 subprocess.call()
Windows에서 다음과 같이 표시되어야합니다.
import subprocess
subprocess.call(('cmd', '/C', 'start', '', FILE_NAME))
다음을 사용할 수 없습니다.
subprocess.call(('start', FILE_NAME))
때문에 start
실행 파일이 아니라 cmd.exe
프로그램 의 명령 입니다 . 이것은 작동합니다 :
subprocess.call(('cmd', '/C', 'start', FILE_NAME))
하지만 FILE_NAME에 공백이없는 경우에만 가능합니다.
while subprocess.call
방법en 는 매개 변수를 적절하게 인용start
명령에는 다소 이상한 구문이 있습니다.
start notes.txt
다음 이외의 작업을 수행합니다.
start "notes.txt"
첫 번째 인용 문자열은 창의 제목을 설정해야합니다. 공간에서 작동하도록하려면 다음을 수행해야합니다.
start "" "my notes.txt"
그게 위에있는 코드가하는 일입니다.
