আমার উইন্ডোজ এবং ম্যাক ওএসে ডিফল্ট অ্যাপ্লিকেশনটি ব্যবহার করে একটি দস্তাবেজ খুলতে সক্ষম হওয়া দরকার। মূলত, আমি একই জিনিসটি করতে চাই যখন আপনি এক্সপ্লোরার বা ফাইন্ডারে নথি আইকনে ডাবল ক্লিক করেন। পাইথনে এটি করার সর্বোত্তম উপায় কী?
আমার উইন্ডোজ এবং ম্যাক ওএসে ডিফল্ট অ্যাপ্লিকেশনটি ব্যবহার করে একটি দস্তাবেজ খুলতে সক্ষম হওয়া দরকার। মূলত, আমি একই জিনিসটি করতে চাই যখন আপনি এক্সপ্লোরার বা ফাইন্ডারে নথি আইকনে ডাবল ক্লিক করেন। পাইথনে এটি করার সর্বোত্তম উপায় কী?
উত্তর:
openএবং startএটি যথাক্রমে ম্যাক ওএস / এক্স এবং উইন্ডোজের কমান্ড-দোভাষী রয়েছে things
পাইথন থেকে তাদের কল করতে, আপনি হয় subprocessমডিউল ব্যবহার করতে পারেন বা os.system()।
কোন প্যাকেজটি ব্যবহার করতে হবে তা এখানে বিবেচনা করা হচ্ছে:
আপনি তাদের মাধ্যমে কল করতে পারেন os.system, যা কাজ করে তবে ...
এস্কেপিং: os.system কেবলমাত্র ফাইলের নামগুলির সাথে কাজ করে যা পাথনামে (যেমন A:\abc\def\a.txt) কোনও ফাঁকা জায়গা বা অন্যান্য শেল মেটাচার্যাক্টর নেই, অন্যথায় এড়াতে হবে। নেই shlex.quoteইউনিক্স-সদৃশ সিস্টেমের জন্য, কিন্তু সত্যিই Windows এর জন্য মান নেই। হয়তো আরো দেখুন পাইথন, উইন্ডোজ: পার্স কমান্ড shlex সঙ্গে লাইন
os.system("open " + shlex.quote(filename))os.system("start " + filename)যেখানে যথাযথভাবে কথা বলতে গেলে এড়ানো filenameউচিত।আপনি তাদের 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।
filenameফর্মটি কোথায় আসে তার উপর নির্ভর করে , কেন os.sismm () নিরাপদ এবং খারাপ এটির একটি নিখুঁত উদাহরণ। সাবপ্রসেস ভাল হয়।
os.system()হ'ল এটি শেলটি ব্যবহার করে (এবং আপনি এখানে কোনও শেল পলায়নের কাজ করছেন না, সুতরাং শেল মেটা-অক্ষরগুলি ধারণ করে এমন পুরোপুরি বৈধ ফাইলনামগুলির জন্য খারাপ জিনিসগুলি ঘটবে)। subprocess.call()পছন্দের কারণটি হ'ল আপনার কাছে শেলটি ব্যবহার করে বাইপাস করার বিকল্প রয়েছে subprocess.call(["open", filename])। এটি সমস্ত বৈধ ফাইলের নামের জন্য কাজ করে এবং অবিশ্বস্ত ফাইলের নামের জন্যও শেল-ইনজেকশন দুর্বলতার পরিচয় দেয় না।
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এটি ফ্রি ডেস্কটপ ফাউন্ডেশন স্ট্যান্ডার্ড এবং লিনাক্স ডেস্কটপ পরিবেশে কাজ করে।
xdg-open- linux.die.net/man/1/xdg-open
xdg-open test.pyএবং এটি আমার জন্য ফায়ারফক্স ডাউনলোড ডায়লগ খুলল। কোনো সমস্যা? আমি মাঞ্জারো লিনাক্স এ আছি
xdg-openকনফিগারেশনের মতো শব্দগুলি বিভ্রান্ত হয়ে পড়েছে, তবে এটি কোনও মন্তব্যে আমরা সমস্যা সমাধান করতে পারি এমন কিছুই নয়। হতে পারে unix.stackexchange.com/questions/36380/…
আমি পছন্দ করি:
os.startfile(path, 'open')
নোট করুন যে এই মডিউলটি ফাইলের নামগুলি সমর্থন করে যাগুলির ফোল্ডারে এবং ফাইলগুলির মধ্যে ফাঁকা স্থান রয়েছে eg
A:\abc\folder with spaces\file with-spaces.txt
( পাইথন ডক্স ) 'ওপেন' যুক্ত করতে হবে না (এটি ডিফল্ট)। দস্তাবেজগুলি বিশেষভাবে উল্লেখ করেছে যে এটি উইন্ডোজ এক্সপ্লোরারের কোনও ফাইলের আইকনে ডাবল ক্লিক করার মতো।
এই সমাধানটি কেবল উইন্ডোজ।
startfileফাংশনটি উপস্থিত নেই, যার অর্থ ব্যবহারকারীরা অনুপস্থিত ফাংশন সম্পর্কে একটি বিভ্রান্তিকর ত্রুটি বার্তা পাবেন। এটি এড়াতে আপনি প্ল্যাটফর্মটি পরীক্ষা করতে চাইতে পারেন।
কেবল সম্পূর্ণতার জন্য (এটি প্রশ্নে ছিল না), লিনাক্সে এক্সডিজি-ওপেন একই কাজ করবে।
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।
এটি স্ট্যান্ডার্ড লাইব্রেরি এবং এর নাম সত্ত্বেও এটি ফাইলগুলি খোলার চেষ্টা করবে:
মনে রাখবেন যে কয়েকটি প্ল্যাটফর্মে, এই ফাংশনটি ব্যবহার করে কোনও ফাইল নাম খোলার চেষ্টা করা অপারেটিং সিস্টেমের সম্পর্কিত প্রোগ্রামটি কাজ করতে এবং শুরু করতে পারে। তবে এটি সমর্থিত নয় বা বহনযোগ্যও নয়। ( রেফারেন্স )
আমি এই কোডটি চেষ্টা করেছিলাম এবং এটি উইন্ডোজ 7 এবং উবুন্টু নাট্টিতে দুর্দান্ত কাজ করেছে:
import webbrowser
webbrowser.open("path_to_file")
এই কোডটি উইন্ডোজ এক্সপি পেশাদারেও ইন্টারনেট এক্সপ্লোরার 8 ব্যবহার করে সূক্ষ্মভাবে কাজ করে।
open locationসেখানে ব্যবহার করে যা কার্যকর হওয়া উচিত যদি আপনি কোনও বৈধ url হিসাবে পথ দেন।
import webbrowser webbrowser.open("file:///Users/nameGoesHere/Desktop/folder/file.py")
আপনি যদি 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"
উপরের কোডটি যা করে।
সূচনা দীর্ঘ পথের নাম এবং সাদা স্থানগুলিকে সমর্থন করে না। আপনাকে এটি 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 )
এপিআই কল সহ কাজ করার জন্য ফাইলটির উপস্থিতি থাকতে হবে।
start "Title" "C:\long path to\file.avi"
আমি অনেক দেরিতে আছি, তবে উইন্ডোজ এপিআই ব্যবহার করে এখানে একটি সমাধান দেওয়া হচ্ছে। এটি সর্বদা সম্পর্কিত অ্যাপ্লিকেশনটি খোলে।
import ctypes
shell32 = ctypes.windll.shell32
file = 'somedocument.doc'
shell32.ShellExecuteA(0,"open",file,0,0,5)
প্রচুর ম্যাজিক কনস্ট্যান্ট। প্রথম শূন্যটি হ'ল বর্তমান প্রোগ্রামের এইচএনডাব্লু। শূন্য হতে পারে। অন্য দুটি শূন্য হ'ল alচ্ছিক পরামিতি (পরামিতি এবং ডিরেক্টরি)। 5 == SW_SHOW, এটি অ্যাপটিকে কীভাবে কার্যকর করা যায় তা নির্দিষ্ট করে। আরও তথ্যের জন্য ShellExecute API ডক্স পড়ুন ।
os.startfile(file)?
আপনি যদি ম্যাক ওএস এক্সে ফাইলটি খুলতে অ্যাপ্লিকেশনটি নির্দিষ্ট করতে চান তবে এটি ব্যবহার করুন:
os.system("open -a [app name] [file name]")
উইন্ডোজ ৮.১-এ, নীচে কাজ করেছে যখন পথের সাথে 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))