sys মডিউল

sys মডিউল #

এ অধ্যায়ে আমরা সিস্টেম-স্পেসিফিক কিছু প্যারামিটার ও ফাংশন নিয়ে আলোচনা করব। আর এসবের সাপ্লাই আসবে সিস্টেম মডিউল সংক্ষেপে sys মডিউল থেকে।

sys.argv #

সকালে উঠিয়া আমি মনে মনে বলি, পাইথন স্ক্রিপ্টের কাছে কিছু আর্গুমেন্ট পাচার করি। কমান্ডলাইনের মাধ্যমে খুব সহজেই আমরা পাইথন স্ক্রিপ্টে আর্গুমেন্ট পাস করতে পারি। এটা নিয়ে অতটা ভাবনা-চিন্তার অবকাশ নেই। কিন্তু সমস্যা হলো পাচার করা সেই আর্গুমেন্টগুলো স্ক্রিপ্টের মধ্যে পড়ব কীভাবে?

বুদ্ধিমানের জন্য ইশারাই যথেষ্ট। আমরা অবশ্যই বুঝে গেছি যে, এ জন্য আমাদের sys.argv-কে ব্যবহার করতে হবে। তবে এখানে জানার মতো একটা মজার জিনিস আছে। sys.argv আসলে কোনো ফাংশন নয়; বরং এটি একটি লিস্ট। আমাদের test.py ফাইলে একটা ছোট্ট গুলুগুলু মতো প্রোগ্রাম লেখা যাক:

import sys

print(sys.argv)
print(type(sys.argv))

for arg in sys.argv:
    print(arg)

এবার আমরা টার্মিনালে কমান্ড দিয়ে এই স্ক্রিপ্টটা রান করাব। পাশাপাশি এটাতে কিছু আর্গুমেন্টও পাচার করব।

$ python3 test.py 1 2 3 4 5

আউটপুট

['test.py', '1', '2', '3', '4', '5']
<class 'list'>
test.py
1
2
3
4
5

আমরা আমাদের স্ক্রিপ্টে 1 2 3 4 5-কে আর্গুমেন্ট হিসেবে পাস করেছি। এসব আর্গুমেন্ট sys.argv লিস্টে জমা হয়েছে। সবচেয়ে মজার বিষয় হলো, এই লিস্টের ইনডেক্স 0-তে খোদ স্ক্রিপ্ট নিজেই আছে। আর আমাদের দেওয়া আর্গুমেন্টগুলো আছে ইনডেক্স 1 থেকে। আসলে sys.argv লিস্টের প্রথম আইটেম ওই স্ক্রিপ্ট নিজেই।

sys.exc_info() #

এটা একটা ইন্টারেস্টিং ফাংশন। এই ফাংশন একটা টাপল রিটার্ন করে। যে এক্সেপশনটা বর্তমানে হ্যান্ডেল হচ্ছে, সেটা সম্পর্কিত তিনটি ইনফরমেটিভ ভ্যালু থাকে টাপলটায়। আর পুরো সিস্টেমে কোনো এক্সেপশন হ্যান্ডেল না হলে তিনটি None ভ্যালু থাকে টাপলে। যেমন :

import sys

try:
    print(10/0)
except ZeroDivisionError:
    print(sys.exc_info())

আউটপুট

(<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero',), <traceback object at 0x7fc456767588>)

ZeroDivisionError এক্সেপশন হ্যান্ডেল করার সময় আমরা sys.exc_info () ফাংশনটার আউটপুট প্রিন্ট করে দেখেছি। হ্যাঁ, এটাই টাপল ও টাপলে তিনটি আইটেমও আছে। আর সেসব আইটেমে এক্সেপশন-সম্পর্কিত তথ্য বিদ্যমান।

sys.executable #

এটা মূলত একটি স্ট্রিং। পাইথন ইন্টারপ্রিটারের এক্সিকিউটেবলের পাথ পাওয়া যায় এখানে (শুধু পাইথন ইন্টারপ্রিটারের প্রচারের জন্য)।

>>> import sys
>>> print(sys.executable)
/usr/bin/python3

sys.exit() #

পাইথন থেকে বের হয়ে যাওয়ার জন্য এই ফাংশনটা ব্যবহৃত হয়। মন চাইলে একটা প্যারামিটার পাস করা যায়। না করলে কোনো ক্ষতি নেই। প্যারামিটারটি ইন্টিজার হতে পারে (সে ক্ষেত্রে ডিফল্ট ভ্যালু হলো জিরো) বা অন্য টাইপের অবজেক্টও হতে পারে। ইন্টিজারটি মূলত স্ট্যাটাস কোড। স্ট্যাটাস কোড জিরো মানে ‘সাকসেসফুল টার্মিনেশন’ এবং নন-জিরো মানে ‘অ্যাবনরমাল টার্মিনেশন’। তবে অপারেটিং সিস্টেমভেদে হয়তো কিছুটা পরিবর্তন থাকতে পারে। একটা উদাহরণ দেখা যাক :

>>> import sys
>>> sys.exit()

এবার আরেকটা উদাহরণ দেখা যাক :

>>> import sys
>>> sys.exit(1)

আউটপুট আপাতভাবে এক হলেও এর মধ্যে পার্থক্য আছে :

>>> import sys
>>> sys.exit("some error message")
some error message

এটা হলো একটা প্রোগ্রামকে নগদে জায়গায় বন্ধ করে দেওয়ার মুশকিল আসান তরিকা। আর আরেকটা ব্যাপার, আমরা যখন এই ফাংশনটি কল করি, তখন SystemExit এক্সেপশন রেইজ হয়।

sys.path #

sys.path হলো স্ট্রিংয়ের লিস্ট যেখানে মিডিউলের সার্চপাথ থাকে। আরেকটু সহজভাবে বলতে গেলে, sys.path হলো একটা লিস্ট আর লিস্টের আইটেম হলো আমাদের কম্পিউটারের বিভিন্ন লোকেশন। যখন আমরা প্রোগ্রামে কোনো মডিউল আমদানি (ইমপোর্ট) করে কাজ করি, তখন পাইথন স্বয়ংক্রিয়ভাবে এসব লোকেশনে সার্চ করে মডিউলটাকে আমদানি করার চেষ্টা করে। আর না পারলে ImportError এক্সেপশন থ্রো করে।

>>> import sys
>>> type(sys.path)
<class 'list'>
>>> len(sys.path)
8
>>> sys.path
['', '/usr/lib/python3/dist-packages', '/usr/local/lib/python3.9/dist-packages/Mezzanine-4.2.0-py3.9.egg', '/usr/lib/python36.zip', '/usr/lib/python3.9', '/usr/lib/python3.9/plat-x86_64-linux-gnu', '/usr/lib/python3.9/lib-dynload', '/usr/local/lib/python3.9/dist-packages']
>>> for path in sys.path:
...       print(path)
...
/usr/lib/python3/dist-packages
/usr/local/lib/python3.9/dist-packages/Mezzanine-4.2.0-py3.9.egg
/usr/lib/python36.zip
/usr/lib/python3.9
/usr/lib/python3.9/plat-x86_64-linux-gnu
/usr/lib/python3.9/lib-dynload
/usr/local/lib/python3.9/dist-packages

এখানে খেয়াল করলে দেখা যাবে sys.path[0] এ কিছু নেই, একটা ফাঁকা স্ট্রিং। এর কারণ হলো, প্রথম সার্চপাথটা হলো স্ক্রিপ্টটা যে ডিরেক্টরিতে আছে, সেই ডিরেক্টরিটা। এরপর পর্যায়ক্রমে পাইথন ইনডেক্স অনুসারে অন্যান্য লোকেশনে সার্চ করে। আমরা চাইলে সিস্টেম পাথে নতুন লোকেশন যোগ করতে পারি। উদাহরণ দেখা যাক :

>>> sys.path.append('/home/maateen')
>>> sys.path
['', '/usr/lib/python3/dist-packages', '/usr/local/lib/python3.9/dist-packages/Mezzanine-4.2.0-py3.9.egg', '/usr/lib/python35.zip', '/usr/lib/python3.9', '/usr/lib/python3.9/plat-x86_64-linux-gnu', '/usr/lib/python3.9/lib-dynload', '/usr/local/lib/python3.9/dist-packages', '/home/maateen']

এখানে আমাদের অ্যাপেন্ড করা লোকেশনটা যোগ হয়েছে।

sys.platform #

sys.platform এ প্ল্যাটফরম আইডেন্টিফায়ার স্ট্রিং থাকে। আসলে বর্তমানে আমরা যে অপারেটিং সিস্টেমে পাইথন চালাচ্ছি তার নামধাম পাওয়ার জন্যই এই sys.platform ব্যবহার করা হয়। অনেক সময় দেখা যায়, অপারেটিং সিস্টেম বদলের কারণে কোডের লজিকে পরিবর্তন করা লাগতে পারে। সেসব ক্ষেত্রে sys.platform ব্যবহার করে বিভিন্ন প্ল্যাটফরমের জন্য বিভিন্ন লজিক লেখা সম্ভব।

>>> import sys
>>> sys.platform
'linux'

আমি লিনাক্স ডিস্ট্রো উবুন্টু ব্যবহার করছি, তাই আমার আইডেন্টিফায়ার linux। এরকমভাবে প্রতিটি ওএসের জন্য আলাদা আলাদা আইডেন্টিফায়ার আছে।

একনজরে সবগুলো আইডেন্টিফায়ার দেখে নেওয়া যাক :

অপারেটিং সিস্টেমপ্ল্যাটফরম ভ্যালু
Linuxlinux
Windowswin32
Windows/Cygwincygwin
Mac OS Xdarwin

sys.stdin, sys.stdout ও sys.stderr #

এগুলো হলো ফাইল অবজেক্ট। স্ট্যান্ডার্ড ইনপুট, আউটপুট ও এররের জন্য ইন্টারপ্রিটার এগুলো ব্যবহার করে থাকে :

  • input() সহ সব ইন্টারেক্টিভ ইনপুটের ক্ষেত্রে stdin ব্যবহৃত হয়।
  • print() ও এক্সপ্রেশন স্টেটমেন্টের আউটপুট এবং input()-এর প্রম্পটের (prompt) জন্য stdout ব্যবহৃত হয়।
  • ইন্টারপ্রিটারের নিজস্ব প্রম্পট (prompt) ও এরর মেসেজ stderr-এর মাধ্যমে হ্যান্ডেল হয়।

অনেক সময় stdout ও stderr-এর আউটপুট কাস্টম লগে রাখার দরকার হতে পারে। এ জন্যই শিখে নেওয়া। এ বিষয়ে আরও বেশি জানার জন্য পাইথনের অফিশিয়াল ডকুমেন্টেশনে ঘুরে আসতে পারেন।

মন্তব্য করুন