گرفتن آرگومانهای کامندلاین در پایتون
# معرفی
با محبوبتر شدن پایتون، توسعه دهندگان از آن برای انواع مختلفی از برنامهها استفاده میکنند. یکی از این انواع، ابزارهای کامندلاینی(cmd) هستند. در پایتون میتوانید ابزارهای ساده تا پیچیده کامندلاینی مانند amazon awscli را بسازید. بخش مهمی از این ابزارها با استفاده از آرگومانها کار میکنند که به کاربر اجازه میدهند دستورات را مشخص کرده و برای آنها آپشن مناسب را انتخاب کنند. برای مثال این آپشنها میتوانند به ابزار بگویند که اطلاعات بیشتری را نمایش دهد، اطلاعات را از منابع خاصی بخوانند یا خروجی را به بخش دیگری ارسال کنند.
به طور کلی، آرگومانها نسبت به سیستم عامل شما به شکل متفاوتی ارسال میشوند:
- در سیستم های یونیکسی با استفاده از - یا -- مشخص میشوند مانند help--
- در ویندوز با / مشخص میشود مانند help/
این تفاوت ریشه در یک اختلاف تاریخی دارد. اکثر ابزارهای یونیکسی از هر دو - و -- پشتیبانی میکنند. یک خط تیره معمولا به شکل خلاصه با یک کاراکتر کار میکند، در حالی که دو خط تیره برای خوانایی بیشتر به طور کامل آپشن را شرح میدهند.
در این مقاله ما فقط با حالت یونیکسی کار میکنیم.
مقاله پیشنهادی: کار با صدا در پایتون
# مدیریت آرگومانهای ترمینال در پایتون
پایتون از روشهای مختلفی برای کار با آرگومانهای کامند لاین پشتیبانی میکند. یکی از این روشها استفاده از ماژول sys است. این ماژول مربوط به کتابخانه libc زبان C است. روش بعدی استفاده از ماژول getopt است که از آپشنهای کوتاه و بلند و اعتبارسنجی آرگومانها پشتیبانی میکند. ماژول دیگری که میتوانید از آنها استفاده کنید ماژول argparse که در کتابخانه استاندارد پایتون است و کتابخانه docopt است که باید به صورت جداگانه نصب شود.
همه این روشها مزایا و معایب خاصی دارند که باید با آنها کار کنید و تصمیم بگیرید که کدام برای شما مناسب تر است.
ویدیو مرتبط: ویدیو آموزش ماژول sys در پایتون
+ ماژول sys پایتون
ابتدایی ترین ابزاری که وجود دارد ماژول sys است. بسیار شبیه به زبان C بوده و از argc/argv برای دسترسی به آرگومان ها استفاده میکند. این ماژول آرگومانها را در یک لیست ذخیره کرده که از sys.argv در دسترس است.
هر آیتم لیست اشاره به یک آرگومان دارد. اولین آیتم لیست، sys.argv[0] نام اسکریپت است. بقیه آیتمهای لیست به آرگومانها اشاره دارند. از فاصله به عنوان جداکننده آرگومانها استفاده میشود. اگر قرار باشد آرگومان با فاصله ارسال شود، باید در یک کوتیشن قرار گیرند.
در اولین مثال، کد زیر آرگومان صفرم که نام اسکریپت است را گرفته و چاپ میکند:
import sys
print ("The script has the name %s" % (sys.argv[0])
این کد را در فایلی به نام arguments-program-name.py ذخیره کرده و اجرا کنید. بعد از اجرا نتیجه زیر را میدهد:
$ python arguments-program-name.py
The script has the name arguments-program-name.py
$ python /home/user/arguments-program-name.py
The script has the name /home/user/arguments-program-name.py
به عنوان مثال دوم، ما فقط تعداد آرگومانهای ارسالی به اسکریپت را میشماریم. در کد پایین ما کل sys.argv را چاپ میکنیم. قبل از چاپ، تعداد sys.argv را منهای یک کرده تا نام اسکریپت کم شود:
import sys
# Count the arguments
arguments = len(sys.argv) - 1
print ("The script is called with %i arguments" % (arguments))
این فایل را با نام arguments-count.py ذخیره کرده و با تعداد آرگومانهای مختلف آن را صدا میزنیم:
$ python arguments-count.py
The script is called with 0 arguments
$ python arguments-count.py --help me
The script is called with 2 arguments
$ python arguments-count.py --option "long string"
The script is called with 2 arguments
در مثال سوم ما تمام آرگومانهای ارسالی را به جز نام اسکریپت چاپ میکنیم:
import sys
# Count the arguments
arguments = len(sys.argv) - 1
# Output argument-wise
position = 1
while (arguments >= position):
print ("Parameter %i: %s" % (position, sys.argv[position]))
position = position + 1
دوباره کدمان را با نام arguments-output.py ذخیره کرده و با تعدا آرگومانهای مختلف صدا میزنیم:
$ python arguments-output.py
$ python arguments-output.py --help me
Parameter 1: --help
Parameter 2: me
$ python arguments-output.py --option "long string"
Parameter 1: --option
Parameter 2: long string
در مثال بالا دقت کنید، آرگومانهایی که در کوتیشن قرار گرفتهاند به عنوان یک آرگومان در نظر گرفته میشوند.
مقاله پیشنهادی: خواندن خط به خط فایل در پایتون
+ ماژول getopt پایتون
همانطور که در بخش قبل متوجه شدید، ماژول sys به شکل تک بعدی با آرگومانها کار میکند. ماژول getops یک قدم فراتر رفته و اعتبار سنجی آرگومان ها را نیز اضافه کرده است. این ماژول بر پایه ماژول getopt زبان C بوده و از آپشنهای کوتاه و بلند پشتیبانی میکند. ماژول getops از ماژول sys استفاده میکند پس باید هر دو این ماژولها را import کنید. بعد از این، اولین آرگومان از لیست پارامترها را حذف کرده و بقیه آرگومان ها را در لیستی به نام argument_list ذخیره میکنیم:
# Include standard modules
import getopt, sys
# Get full command-line arguments
full_cmd_arguments = sys.argv
# Keep all but the first
argument_list = full_cmd_arguments[1:]
print(argument_list)
حالا میتوانید از ماژول getops برای کار با آرگومان های argument_list استفاده کنید. اما قبل از اینکار باید به ماژول getops بگویید که کدام آرگومان ها معتبر هستند:
short_options = "ho:v"
long_options = ["help", "output=", "verbose"]
این یعنی اینها آرگومان های معتبر هستند، به همراه اطلاعاتی بیشتر:
------------------------------------------
long argument short argument with value
------------------------------------------
--help -h no
--output -o yes
--verbose -v no
------------------------------------------
شاید متوجه شده باشید که آرگومان o با یک دونقطه از هم جدا شدهاند، این به getops میگوید که این آپشت باید به یک متغیر منسوب شود.
حالا میتوانید با آرگومان ها کار کنید. ماژول getops به سه پارامتر نیاز دارد، لیست آرگومانهای argv و آپشنهای کوتاه و بلند.
صدا زدن متد در یک بلوک try...except قرار گرفته تا بتواند خطاهای احتمالی را کنترل کند. خطا زمانی رخ میدهد که آرگومانی که نیاز نیست ارسال شود. در این حالت پیغام خطا چاپ شده و با کد ارور 2 اسکریپت متوقف میشود:
try:
arguments, values = getopt.getopt(argument_list, short_options, long_options)
except getopt.error as err:
# Output error, and return with an error code
print (str(err))
sys.exit(2)
در نهایت، آرگومان های با مقادیر مربوطه در دو متغیر به نام های arguments و values ذخیره می شوند. اکنون می توانید به راحتی این متغیرها را در کد خود استفاده کنید. ما میتوانیم از یک حلقه for برای پیمایش در لیست آرگومانهای شناسایی شده استفاده کنیم:
# Evaluate given options
for current_argument, current_value in arguments:
if current_argument in ("-v", "--verbose"):
print ("Enabling verbose mode")
elif current_argument in ("-h", "--help"):
print ("Displaying help")
elif current_argument in ("-o", "--output"):
print (("Enabling special output mode (%s)") % (current_value))
در زیر، خروجی اجرای این کد را مشاهده می کنید. ما نشان خواهیم داد که چگونه برنامه با آرگومان های معتبر و نامعتبر برنامه واکنش نشان می دهد:
$ python arguments-getopt.py -h
Displaying help
$ python arguments-getopt.py --help
Displaying help
$ python arguments-getopt.py --output=green --help -v
Enabling special output mode (green)
Displaying help
Enabling verbose mode
$ python arguments-getopt.py -verbose
option -e not recognized
آخرین فراخوانی برنامه ما ممکن است در ابتدا کمی گیج کننده به نظر برسد. برای درک آن، باید بدانید که گزینههای کوتاهنویسی (که گاهی پرچم نیز نامیده میشود) را میتوان همراه با یک خط تیره استفاده کرد. این به ابزار شما اجازه میدهد تا بسیاری از گزینهها را راحتتر بپذیرد. برای مثال، فراخوانی python arguments-getopt.py -vh مانند فراخوانی python arguments-getopt.py -v -h است. بنابراین در آخرین فراخوانی بالا، ماژول getopt فکر میکرد که کاربر سعی میکند -e را بهعنوان یک گزینه ارسال کند، که نامعتبر است.
ویدیو مرتبط: ویدیو آموزش ماژول argparse پایتون
+ ماژول argparse پایتون
ماژول argparse از زمان پایتون 3.2 در دسترس بوده است و نسخه بهبود یافته ماژول optparse است که تا پایتون 2.7 وجود داشت. مستندات پایتون حاوی توضیحات API و یک آموزش است که تمام روش ها را با جزئیات پوشش می دهد.
این ماژول یک رابط خط فرمان با خروجی استاندارد ارائه می دهد، در حالی که دو راه حل قبلی بیشتر کار را در دستان شما می گذارند. argparse امکان تأیید آرگومان های ثابت و اختیاری را با بررسی نام به صورت کوتاه یا طولانی فراهم می کند. همچنین این ماژول به صورت پیشفرض دارای آرگومان h- است یک صفحه راهنما در اختیار شما قرار میدهد و آرگومان های پذیرفته شده را توصیف می کند.
کد زیر یک مثال پایه از ماژول arparse را نشان میدهد که به همراه صفحه راهنما ایجاد شده است:
# Include standard modules
import argparse
# Initiate the parser
parser = argparse.ArgumentParser()
parser.parse_args()
$ python3 arguments-argparse-basic.py
$ python3 arguments-argparse-basic.py -h
usage: arguments-argparse-basic.py [-h]
optional arguments:
-h, --help show this help message and exit
$ python3 arguments-argparse-basic.py --verbose
usage: arguments-argparse-basic.py [-h]
arguments-argparse-basic.py: error: unrecognized arguments: --verbose
در مرحله بعد، یک توضیح به صفحه راهنما برای کاربران خود اضافه می کنیم. میتوانید توضیحات خود را در قالب یک string به کلاس ArgumentParser اضافه کنید:
# Include standard modules
import argparse
# Define the program description
text = 'This is a test program. It demonstrates how to use the argparse module with a program description.'
# Initiate the parser with a description
parser = argparse.ArgumentParser(description=text)
parser.parse_args()
$ python3 arguments-argparse-description.py --help
usage: arguments-argparse-description.py [-h]
This is a test program. It demonstrates how to use the argparse module with a
program description.
optional arguments:
-h, --help show this help message and exit
به عنوان مرحله آخر ما یک آپشن که در حالت کوتاه V- و در حالت بلند verbose-- است را به برنامه اضافه میکنیم. برای اینکار باید از متد add_argument استفاده کنیم که سه مقدار میگیرد: نام پارامتر، پیام کمکی و عملیات.
کد زیر این کار را برای ما انجام میدهد. برای گرفتن آرگومانها باید parse_args را در یک متغیر ذخیره کرده و از آن متغیر استفاده کنید:
# Include standard modules
import argparse
# Initiate the parser
parser = argparse.ArgumentParser()
parser.add_argument("-V", "--version", help="show program version", action="store_true")
# Read arguments from the command line
args = parser.parse_args()
# Check for --version or -V
if args.version:
print("This is myprogram version 0.1")
$ python3 arguments-argparse-optional.py -V
This is myprogram version 0.1
$ python3 arguments-argparse-optional.py --version
This is myprogram version 0.1
آپشن version-- نیازی به مقدار ندارد چونکه در این آپشن action را برابر با store_true گذاشته ایم. این مقدار باعث میشود که در صورت وجود version-- مقدار آن به طور اتوماتیک True شود:
# Include standard modules
import argparse
# Initiate the parser
parser = argparse.ArgumentParser()
# Add long and short argument
parser.add_argument("--width", "-w", help="set output width")
# Read arguments from the command line
args = parser.parse_args()
# Check for --width
if args.width:
print("Set output width to %s" % args.width)
$ python3 arguments-argparse-optional2.py -w 10
Set output width to 10
$ python3 arguments-argparse-optional2.py --width 10
Set output width to 10
$ python3 arguments-argparse-optional2.py -h
usage: arguments-argparse-optional2.py [-h] [--width WIDTH]
optional arguments:
-h, --help show this help message and exit
--width WIDTH, -w WIDTH
set output width
مقاله پیشنهادی: پایتون سریعتر با PyPy
# نتیجه گیری
در این مقاله روشهای مختلفی را برای بازیابی آرگومانهای خط فرمان در پایتون نشان دادیم، از جمله استفاده از sys، getopt و argparse. این ماژول ها از نظر عملکرد متفاوت هستند، برخی از آنها بسیار بهتر از بقیه هستند. sys کاملاً منعطف است، در حالی که هر دو getopt و argparse به ساختاری نیاز دارند. در مقابل، آنها بیشتر کارهای پیچیده ای را که sys به شما واگذار می کند پوشش می دهند. پس از بررسی مثال های ارائه شده، باید بتوانید تعیین کنید که کدام ماژول برای پروژه شما مناسب تر است.
در این مقاله در مورد راه حل های دیگری مانند ماژول docopts صحبت نکردیم. این ماژول رویکرد کاملا متفاوتی را دنبال می کند و در یکی از مقالات بعدی به تفصیل توضیح داده خواهد شد.