উইন্ডোজ এবং ম্যাক ওএস উভয়ই পাইথনে ডিফল্ট ওএস অ্যাপ্লিকেশন সহ নথি খুলুন


125

আমার উইন্ডোজ এবং ম্যাক ওএসে ডিফল্ট অ্যাপ্লিকেশনটি ব্যবহার করে একটি দস্তাবেজ খুলতে সক্ষম হওয়া দরকার। মূলত, আমি একই জিনিসটি করতে চাই যখন আপনি এক্সপ্লোরার বা ফাইন্ডারে নথি আইকনে ডাবল ক্লিক করেন। পাইথনে এটি করার সর্বোত্তম উপায় কী?


9
২০০৮ সাল থেকে পাইথন ট্র্যাকারে স্ট্যান্ডার্ড লাইব্রেরিতে এটি অন্তর্ভুক্ত করার জন্য একটি সমস্যা রয়েছে: বাগসপিথন.অর্গ.সিসু3177
রাম রাছুম

উত্তর:


77

openএবং startএটি যথাক্রমে ম্যাক ওএস / এক্স এবং উইন্ডোজের কমান্ড-দোভাষী রয়েছে things

পাইথন থেকে তাদের কল করতে, আপনি হয় subprocessমডিউল ব্যবহার করতে পারেন বা os.system()

কোন প্যাকেজটি ব্যবহার করতে হবে তা এখানে বিবেচনা করা হচ্ছে:

  1. আপনি তাদের মাধ্যমে কল করতে পারেন os.system, যা কাজ করে তবে ...

    এস্কেপিং: os.system কেবলমাত্র ফাইলের নামগুলির সাথে কাজ করে যা পাথনামে (যেমন A:\abc\def\a.txt) কোনও ফাঁকা জায়গা বা অন্যান্য শেল মেটাচার্যাক্টর নেই, অন্যথায় এড়াতে হবে। নেই shlex.quoteইউনিক্স-সদৃশ সিস্টেমের জন্য, কিন্তু সত্যিই Windows এর জন্য মান নেই। হয়তো আরো দেখুন পাইথন, উইন্ডোজ: পার্স কমান্ড shlex সঙ্গে লাইন

    • MacOS এর / এক্স: os.system("open " + shlex.quote(filename))
    • উইন্ডোজ: os.system("start " + filename)যেখানে যথাযথভাবে কথা বলতে গেলে এড়ানো filenameউচিত।
  2. আপনি তাদের subprocessমডিউল মাধ্যমে কল করতে পারেন , কিন্তু ...

    পাইথন ২.7 এবং আরও নতুনদের জন্য, সহজভাবে ব্যবহার করুন

    subprocess.check_call(['open', filename])

    পাইথন ৩.৫+ তে আপনি সমানভাবে আরও কিছুটা জটিল ব্যবহার করতে পারেন তবে কিছুটা বহুমুখীও

    subprocess.run(['open', filename], check=True)

    পাইথন ২.৪-এ ফিরে যেতে যদি আপনাকে সমস্ত উপায়ে সামঞ্জস্য বজায় রাখতে হয় তবে আপনি 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যা ব্যবহার করে বেনিফিট অধিকাংশ negates subprocess


2
filenameফর্মটি কোথায় আসে তার উপর নির্ভর করে , কেন os.sismm () নিরাপদ এবং খারাপ এটির একটি নিখুঁত উদাহরণ। সাবপ্রসেস ভাল হয়।
ডেভিন জিনপিয়ের

6
নিকের উত্তরটি আমার কাছে ভাল লাগছিল। কিছুতেই পেল না। ভুল উদাহরণ ব্যবহার করে জিনিস ব্যাখ্যা করা সহজেই ন্যায়সঙ্গত হয় না।
ডেভিন জিনপিয়ের

2
এটি সাবপ্রসেস ব্যবহারের চেয়ে কম সুরক্ষিত এবং কম নমনীয়। এটা আমার কাছে ভুল মনে হচ্ছে
ডেভিন জিনপিয়েরে

8
অবশ্যই এটি গুরুত্বপূর্ণ। এটি একটি ভাল উত্তর এবং একটি খারাপ উত্তর (বা একটি ভয়ঙ্কর উত্তর) মধ্যে পার্থক্য। ওএস.সিস্টেমের জন্য ডকগুলি () নিজেরাই বলছে "সাবপ্রসেস মডিউলটি ব্যবহার করুন।" আর কি দরকার? এটা আমার পক্ষে অবমূল্যায়ন যথেষ্ট।
ডেভিন জিনপিয়ের

20
আমি এই আলোচনাটি পুনরায় আরম্ভ করতে কিছুটা অনিচ্ছুক বোধ করি তবে আমি মনে করি "পরবর্তী আপডেট" বিভাগটি এটি পুরোপুরি ভুল হয়ে গেছে। সমস্যাটি os.system()হ'ল এটি শেলটি ব্যবহার করে (এবং আপনি এখানে কোনও শেল পলায়নের কাজ করছেন না, সুতরাং শেল মেটা-অক্ষরগুলি ধারণ করে এমন পুরোপুরি বৈধ ফাইলনামগুলির জন্য খারাপ জিনিসগুলি ঘটবে)। subprocess.call()পছন্দের কারণটি হ'ল আপনার কাছে শেলটি ব্যবহার করে বাইপাস করার বিকল্প রয়েছে subprocess.call(["open", filename])। এটি সমস্ত বৈধ ফাইলের নামের জন্য কাজ করে এবং অবিশ্বস্ত ফাইলের নামের জন্যও শেল-ইনজেকশন দুর্বলতার পরিচয় দেয় না।
সোভেন মারনাচ

150

subprocessপাইথন ২.৪++ এ উপলব্ধ মডিউলটি ব্যবহার করুন 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-openকমান্ডও রয়েছে যা একই কাজ করে তবে xdg-openএটি ফ্রি ডেস্কটপ ফাউন্ডেশন স্ট্যান্ডার্ড এবং লিনাক্স ডেস্কটপ পরিবেশে কাজ করে।


5
উপ-প্রসেসক্লু'এল 'স্টার্ট' ব্যবহার করা () উইন্ডোজে কাজ করে না - স্টার্টটি কার্যকরভাবে কার্যকর করা যায় না।
টমাস সেদোভিক

4
নিতপিক: সমস্ত লিনাক্সেনে (এবং আমি বেশিরভাগ বিএসডিই অনুমান করি) আপনার ব্যবহার করা উচিত xdg-open- linux.die.net/man/1/xdg-open
gnud

6
উইন্ডোজ শুরু করা একটি শেল কমান্ড, এক্সিকিউটেবল নয়। আপনি সাবপ্রসেসক্ল্যাকাল (('স্টার্ট', ফাইলপথ), শেল = ট্রু) ব্যবহার করতে পারেন, যদিও আপনি যদি শেলটিতে এক্সিকিউট করছেন তবে আপনি ওএস.সিস্টেমও ব্যবহার করতে পারেন।
পিটার গ্রাহাম

আমি দৌড়ে এসেছিলাম xdg-open test.pyএবং এটি আমার জন্য ফায়ারফক্স ডাউনলোড ডায়লগ খুলল। কোনো সমস্যা? আমি মাঞ্জারো লিনাক্স এ আছি
জেসন

1
@ জেসন আপনার xdg-openকনফিগারেশনের মতো শব্দগুলি বিভ্রান্ত হয়ে পড়েছে, তবে এটি কোনও মন্তব্যে আমরা সমস্যা সমাধান করতে পারি এমন কিছুই নয়। হতে পারে unix.stackexchange.com/questions/36380/…
ট্রিপল

44

আমি পছন্দ করি:

os.startfile(path, 'open')

নোট করুন যে এই মডিউলটি ফাইলের নামগুলি সমর্থন করে যাগুলির ফোল্ডারে এবং ফাইলগুলির মধ্যে ফাঁকা স্থান রয়েছে eg

A:\abc\folder with spaces\file with-spaces.txt

( পাইথন ডক্স ) 'ওপেন' যুক্ত করতে হবে না (এটি ডিফল্ট)। দস্তাবেজগুলি বিশেষভাবে উল্লেখ করেছে যে এটি উইন্ডোজ এক্সপ্লোরারের কোনও ফাইলের আইকনে ডাবল ক্লিক করার মতো।

এই সমাধানটি কেবল উইন্ডোজ।


ধন্যবাদ। আমি উপলভ্যতা লক্ষ্য করিনি, যেহেতু ডক্স এটি শেষ অনুচ্ছেদে সংযুক্ত করেছে ended অন্যান্য বিভাগে, প্রাপ্যতা নোটটি তার নিজস্ব লাইন দখল করে।
ডাঃব্লডমনি

কোনও কারণে ত্রুটি বাড়ানোর পরিবর্তে লিনাক্সে, startfileফাংশনটি উপস্থিত নেই, যার অর্থ ব্যবহারকারীরা অনুপস্থিত ফাংশন সম্পর্কে একটি বিভ্রান্তিকর ত্রুটি বার্তা পাবেন। এটি এড়াতে আপনি প্ল্যাটফর্মটি পরীক্ষা করতে চাইতে পারেন।
সিজেড

39

কেবল সম্পূর্ণতার জন্য (এটি প্রশ্নে ছিল না), লিনাক্সে এক্সডিজি-ওপেন একই কাজ করবে।


6
+1 সাধারণত, উত্তরদাতাদের জিজ্ঞাসা করা হয়নি এমন প্রশ্নের উত্তর দেওয়া উচিত নয়, তবে এই ক্ষেত্রে আমি মনে করি এটি সামগ্রিকভাবে SO সম্প্রদায়ের জন্য অত্যন্ত প্রাসঙ্গিক এবং সহায়ক।
demongolem

এই সন্ধান
করছিল

25
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])

2
হু, আমি স্টার্টফিল সম্পর্কে জানতাম না। পাইথনের ম্যাক এবং লিনাক্স সংস্করণগুলি একই রকম শব্দার্থক শব্দগুলি বেছে নিয়েছে তবে এটি দুর্দান্ত।
নিক

3
প্রাসঙ্গিক পাইথন বাগ: bugs.python.org/issue3177 - একটি দুর্দান্ত প্যাচ সরবরাহ করুন এবং এটি গ্রহণযোগ্য হতে পারে =)
gnud

লিনাক্সের জন্য XDG খুলুন কমান্ড
TheTechRobo36414519

21

যদি আপনাকে কোনও হিউরিস্টিক পদ্ধতি ব্যবহার করতে হয় তবে আপনি বিবেচনা করতে পারেন webbrowser
এটি স্ট্যান্ডার্ড লাইব্রেরি এবং এর নাম সত্ত্বেও এটি ফাইলগুলি খোলার চেষ্টা করবে:

মনে রাখবেন যে কয়েকটি প্ল্যাটফর্মে, এই ফাংশনটি ব্যবহার করে কোনও ফাইল নাম খোলার চেষ্টা করা অপারেটিং সিস্টেমের সম্পর্কিত প্রোগ্রামটি কাজ করতে এবং শুরু করতে পারে। তবে এটি সমর্থিত নয় বা বহনযোগ্যও নয়। ( রেফারেন্স )

আমি এই কোডটি চেষ্টা করেছিলাম এবং এটি উইন্ডোজ 7 এবং উবুন্টু নাট্টিতে দুর্দান্ত কাজ করেছে:

import webbrowser
webbrowser.open("path_to_file")

এই কোডটি উইন্ডোজ এক্সপি পেশাদারেও ইন্টারনেট এক্সপ্লোরার 8 ব্যবহার করে সূক্ষ্মভাবে কাজ করে।


3
আমি যতদূর বলতে পারি, এটি এখন পর্যন্ত সেরা উত্তর। ক্রস প্ল্যাটফর্ম মনে হচ্ছে এবং কোন প্ল্যাটফর্মটি ব্যবহার করছে বা ওএস, প্ল্যাটফর্মটি আমদানি করছে তা যাচাই করার দরকার নেই।
পোল্যান্ডার

2
@ জোনাথানরোচার: আমি উত্স কোডে ম্যাক সমর্থন দেখতে পাচ্ছি । এটি open locationসেখানে ব্যবহার করে যা কার্যকর হওয়া উচিত যদি আপনি কোনও বৈধ url হিসাবে পথ দেন।
jfs

1
ম্যাকোস:import webbrowser webbrowser.open("file:///Users/nameGoesHere/Desktop/folder/file.py")
ড্যানিয়েল

3
" docs.python.org/3/library/webbrowser.html#webbrowser.open " লক্ষ্য করুন যে কিছু প্ল্যাটফর্মে [ওয়েবব্রোজার.ওপেন (ইউআরএল)] ব্যবহার করে একটি ফাইলের নাম খোলার চেষ্টা করা অপারেটিং সিস্টেমের সম্পর্কিত প্রোগ্রামটি চালু করতে এবং শুরু করতে পারে However , এটি সমর্থিত বা পোর্টেবলও নয় "
nanpasu64

6

আপনি যদি subprocess.call()পথে যেতে চান তবে এটি উইন্ডোজের মতো দেখতে হবে:

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 এ কোনও স্থান নেই।

subprocess.callপদ্ধতি এন প্যারামিটারগুলি সঠিকভাবে উদ্ধৃত করার সময় , startকমান্ডটির পরিবর্তে একটি অদ্ভুত বাক্য গঠন রয়েছে, যেখানে:

start notes.txt

এর বাইরে অন্য কিছু করে:

start "notes.txt"

প্রথম উদ্ধৃতিযুক্ত স্ট্রিংটিতে উইন্ডোর শিরোনাম সেট করা উচিত। এটি স্পেস দিয়ে কাজ করতে, আমাদের করতে হবে:

start "" "my notes.txt"

উপরের কোডটি যা করে।


5

সূচনা দীর্ঘ পথের নাম এবং সাদা স্থানগুলিকে সমর্থন করে না। আপনাকে এটি 8.3 সামঞ্জস্যপূর্ণ পাথে রূপান্তর করতে হবে।

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 )

এপিআই কল সহ কাজ করার জন্য ফাইলটির উপস্থিতি থাকতে হবে।


1
আরেকটি start "Title" "C:\long path to\file.avi"
কর্মসূচী হ'ল এটিকে

3

আমি অনেক দেরিতে আছি, তবে উইন্ডোজ এপিআই ব্যবহার করে এখানে একটি সমাধান দেওয়া হচ্ছে। এটি সর্বদা সম্পর্কিত অ্যাপ্লিকেশনটি খোলে।

import ctypes

shell32 = ctypes.windll.shell32
file = 'somedocument.doc'

shell32.ShellExecuteA(0,"open",file,0,0,5)

প্রচুর ম্যাজিক কনস্ট্যান্ট। প্রথম শূন্যটি হ'ল বর্তমান প্রোগ্রামের এইচএনডাব্লু। শূন্য হতে পারে। অন্য দুটি শূন্য হ'ল alচ্ছিক পরামিতি (পরামিতি এবং ডিরেক্টরি)। 5 == SW_SHOW, এটি অ্যাপটিকে কীভাবে কার্যকর করা যায় তা নির্দিষ্ট করে। আরও তথ্যের জন্য ShellExecute API ডক্স পড়ুন ।


1
এটা তুলনা কিভাবে os.startfile(file)?
jfs

2

ম্যাক ওএসে আপনি 'খোলা' কল করতে পারেন

import os
os.popen("open myfile.txt")

এটি টেক্সটএডিট দিয়ে ফাইলটি খুলতে পারে বা যে কোনও অ্যাপ্লিকেশন এই ফাইল টাইপের জন্য ডিফল্ট হিসাবে সেট করা আছে


2

আপনি যদি ম্যাক ওএস এক্সে ফাইলটি খুলতে অ্যাপ্লিকেশনটি নির্দিষ্ট করতে চান তবে এটি ব্যবহার করুন: os.system("open -a [app name] [file name]")


2

উইন্ডোজ ৮.১-এ, নীচে কাজ করেছে যখন পথের সাথে subprocess.callব্যর্থতার সাথে দেওয়া অন্যান্য উপায়গুলির মধ্যে ফাঁকা স্থান রয়েছে।

subprocess.call('cmd /c start "" "any file path with spaces"')

এর আগে এবং এর অন্যান্য উত্তরগুলি ব্যবহার করে, এখানে একটি ইনলাইন কোড যা একাধিক প্ল্যাটফর্মগুলিতে কাজ করে।

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))

2

os.startfile(path, 'open')উইন্ডোজের অধীনে ভাল কারণ যখন ডিরেক্টরিতে স্পেসের উপস্থিতি os.system('start', path_name)থাকে, অ্যাপটি সঠিকভাবে খুলতে পারে না এবং যখন আই 18 ডিরেক্টরি ডিরেক্টরিতে উপস্থিত থাকে তখন os.systemউইন্ডোতে কনসোলের কোডেকটিতে ইউনিকোড পরিবর্তন করা দরকার।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.