بررسی اجمالی
از آنجایی که پایتون یک زبان برنامه نویسی بسیار محبوب است، و همچنین پشتیبانی از اکثر سیستم عامل ها و بسیاری از کتابخانه ها که پردازش آرگومان خط فرمان را آسان می کند – به طور گسترده برای ایجاد ابزارهای خط فرمان برای اهداف مختلف استفاده می شود. این ابزارها میتوانند از برنامههای ساده CLI تا برنامههای پیچیدهتر، مانند AWS، متغیر باشند. awscli ابزار است.
ابزارهای پیچیده ای مانند این معمولاً توسط کاربر کنترل می شوند آرگومان های خط فرمان، که به کاربر امکان استفاده از دستورات خاص، تنظیم گزینه ها و موارد دیگر را می دهد. برای مثال، این گزینهها میتوانند به ابزار بگویند اطلاعات اضافی را خروجی کند، دادهها را از یک منبع مشخص بخواند یا خروجی را به یک مکان خاص ارسال کند.
به طور کلی، بسته به سیستم عامل شما، آرگومان ها به روش های متفاوتی به ابزارهای CLI منتقل می شوند:
- یونیکس مانند:
-
به دنبال آن نامه ای مانند-h
، یا--
به دنبال آن یک کلمه، مانند--help
- ویندوز:
/
به دنبال آن یک حرف یا کلمه مانند/help
این رویکردهای متفاوت به دلایل تاریخی وجود دارد. بسیاری از برنامه ها در سیستم های شبه یونیکس از علامت گذاری تک خطی و دوتایی پشتیبانی می کنند. علامت گذاری تک خط بیشتر با گزینه های تک حرفی استفاده می شود، در حالی که خط های دوتایی لیست گزینه های قابل خواندن تری را ارائه می دهند که به ویژه برای گزینه های پیچیده ای که باید واضح تر باشند مفید است.
توجه داشته باشید: در این مقاله ما فقط بر روی فرمت یونیکس مانند تمرکز خواهیم کرد -
و --
.
به خاطر داشته باشید که هم نام و هم معنای یک آرگومان مختص یک برنامه است - هیچ تعریف کلی وجود ندارد، به جز چند قرارداد رایج مانند --help
برای اطلاعات بیشتر در مورد استفاده از ابزار. به عنوان توسعهدهنده یک اسکریپت پایتون، تصمیم میگیرید که کدام آرگومانها را به تماسگیرنده ارائه دهید و چه کاری انجام میدهند. این نیاز به ارزیابی مناسب دارد.
با افزایش فهرست آرگومان های موجود، کد شما در تلاش برای تجزیه دقیق آنها پیچیده تر می شود. خوشبختانه، در پایتون تعدادی کتابخانه برای کمک به شما در این زمینه وجود دارد. ما تعدادی از رایجترین راهحلها را پوشش میدهیم که از «خودت انجام بده» را شامل میشود sys.argv
، به رویکرد "انجام شد برای شما" با argparse
.
مدیریت آرگومان های خط فرمان با پایتون
Python 3+ و اکوسیستم اطراف آن از تعدادی روش مختلف برای مدیریت آرگومان های خط فرمان پشتیبانی می کند. وجود دارد بسیاری کتابخانه هایی که تجزیه آرگومان های خط فرمان را تسهیل می کنند.
راه ساخته شده در استفاده از sys
مدول. از نظر نام و کاربرد آن، مستقیماً به کتابخانه C مربوط می شود (libc
).
راه دوم این است getopt
ماژول، که هر دو گزینه کوتاه و بلند، از جمله ارزیابی مقادیر پارامتر را کنترل می کند.
La ماژول argparse، که مشتق شده از optparse
ماژول (در دسترس تا پایتون 2.7).
La docopt
ماژول، که است در GitHub موجود است، همچنین به همین عملکرد اجازه می دهد.
به تازگی، absl
کتابخانه نیز به عنوان وسیلهای برای جایگزینی، در حال افزایش است optparse
و getopt()
.
هر یک از این راهها مزایا و معایب خود را دارند، بنابراین ارزش ارزیابی هر کدام را دارد تا ببینید کدامیک بیشتر با نیازهای شما مطابقت دارد.
ماژول sys
این یک ماژول اولیه است که از روزهای اولیه با پایتون ارسال شده است. با استفاده از کتابخانه C رویکرد بسیار مشابهی دارد argc
/argv
برای دسترسی به آرگومان ها این ماژول sys آرگومان های خط فرمان را در یک ساختار لیست ساده به نام پیاده سازی می کند sys.argv
.
هر عنصر لیست یک آرگومان واحد را نشان می دهد. اولین مورد در لیست،
sys.argv[0]
، نام اسکریپت پایتون است. بقیه عناصر لیست،sys.argv[1]
بهsys.argv[n]
، آرگومان های خط فرمان 2 تا n هستند.
به عنوان جداکننده بین آرگومان ها، از یک فاصله استفاده می شود. مقادیر آرگومان که حاوی یک فاصله در آن هستند باید با نقل قول احاطه شوند تا به درستی تجزیه شوند sys
.
معادل argc
فقط تعداد عناصر موجود در لیست است. برای بدست آوردن این مقدار از پایتون استفاده کنید len()
اپراتور. بعداً این را در یک مثال کد نشان خواهیم داد.
چاپ اولین آرگومان CLI
در این مثال اول، اسکریپت ما نحوه فراخوانی آن را تعیین می کند. این اطلاعات در اولین آرگومان خط فرمان با 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
همانطور که از فراخوان دوم بالا می بینید، نه تنها نام فایل پایتون، بلکه مسیر کاملی که برای فراخوانی آن استفاده می شود را نیز دریافت می کنیم.
شمارش تعداد آرگومان ها
در این مثال دوم ما به سادگی تعداد آرگومان های خط فرمان را با استفاده از داخلی شمارش می کنیم len()
روش. sys.argv
لیستی است که باید بررسی کنیم. در کد زیر، تعداد آرگومان ها را می گیریم و سپس 1 را کم می کنیم زیرا یکی از آن آرگومان ها (یعنی اولی) همیشه به عنوان نام فایل تنظیم می شود که همیشه برای ما مفید نیست. بنابراین، تعداد واقعی آرگومان های ارسال شده توسط کاربر برابر است len(sys.argv) - 1
:
import sys
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
تکرار از طریق استدلال
مثال سوم ما هر آرگومان فرستاده شده به اسکریپت پایتون را به جز نام خود برنامه خروجی می دهد. بنابراین، از طریق آرگومان های خط فرمان که با the شروع می شوند، حلقه می زنیم دوم عنصر فهرست به یاد داشته باشید که این شاخص 1 است زیرا لیست ها در پایتون مبتنی بر 0 هستند:
import sys
arguments = len(sys.argv) - 1
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
به یاد داشته باشید، نکته نشان دادن مثال رشته نقل شده این است که پارامترها معمولاً با یک فاصله محدود می شوند. مگر آنها توسط نقل قول احاطه شده اند.
پرچم های آبسیل (absl
)
کتابخانه Abseil's Flags قرار است آرگومان های خط فرمان را با آرگومان های خط فرمان توزیع شده به تولید بیاورد. هنگامی که یک ماژول از پرچم های خط فرمان استفاده می کند و به ماژول دیگری - ماژول دیگر وارد می شود پرچم ها را نیز وارد می کند، و می تواند آنها را با ارسال آنها به ماژول وارد شده پردازش کند.
این امر آرگومان های خط فرمان پیچیده ای را که بین ماژول ها به اشتراک گذاشته می شود، آسان تر و پرمخاطب تر می کند.
علاوه بر این، کتابخانه به شما امکان می دهد مقادیر پیش فرض، توضیحات و نوع داده آرگومان ها را تعریف کنید، بنابراین بررسی ها و تبدیل های اضافی لازم نیست.
from absl import flags
import sys
flags.DEFINE_string('name', 'User', 'The name of the user.')
FLAGS = flags.FLAGS
FLAGS(sys.argv)
print(f"Hello {FLAGS.name}!")
انواع داده های پشتیبانی شده عبارتند از:
DEFINE_integer()
DEFINE_string()
DEFINE_bool()
DEFINE_enum()
DEFINE_list()
DEFINE_float()
همچنین DEFINE_multi_integer()
, DEFINE_multi_string()
و DEFINE_multi_enum()
برای ورودی چند آرگومان علاوه بر این، در حال اجرا --help
, --helpfull
و غیره پرچم های موجود و توضیحات آنها را در قالب های مختلف چاپ کنید.
راهنمای عملی و عملی ما برای یادگیری Git را با بهترین روش ها، استانداردهای پذیرفته شده در صنعت و برگه تقلب شامل بررسی کنید. دستورات Google Git را متوقف کنید و در واقع یاد گرفتن آی تی!
این کتابخانه همچنین به شما اجازه میدهد تا اعتبارسنجیها را از نظر محدوده تعریف کنید، مانند مقادیر مبتنی بر اعداد صحیح که دارای یک upper_bound
or lower_bound
این قابل قبول است و روش های دلخواه را برای بررسی مقادیر اجرا می کنید:
def validate_name(value):
return len(value) > 15
flags.register_validator('name',
validate_name,
message='Name is over 15 characters long.',
flag_values=FLAGS)
جمع آوری اینها در یک مثال عینی:
from absl import flags
import sys
flags.DEFINE_string('name', 'User', 'The name of the user.')
flags.DEFINE_integer('tasks', 0, 'The number of tasks a user has.', lower_bound=0)
FLAGS = flags.FLAGS
FLAGS(sys.argv)
print(f"{FLAGS.name} has {FLAGS.tasks} tasks to work on.")
$ python flags.py --name=John --tasks=5
John has 5 tasks to work on.
$ python flags.py --name=John --tasks=-1
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/absl/flags/_flag.py", line 180, in _parse
return self.parser.parse(argument)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/absl/flags/_argument_parser.py", line 168, in parse
raise ValueError('%s is not %s' % (val, self.syntactic_help))
ValueError: -1 is not a non-negative integer
...
ماژول argparse
La ماژول argparse از زمان پایتون 3.2 و بهبود یافته ای در دسترس بوده است optparse
ماژولی که تا پایتون 2.7 وجود دارد. مستندات پایتون حاوی توضیحات API و یک آموزش است که تمام روش ها را با جزئیات پوشش می دهد.
این ماژول یک رابط خط فرمان با یک خروجی استاندارد ارائه می دهد، در حالی که دو راه حل قبلی بیشتر کار را در دستان شما باقی می گذارند. argparse
اجازه می دهد تا آرگومان های ثابت و اختیاری را تأیید کنید، با بررسی نام به صورت کوتاه یا بلند. به عنوان یک آرگومان اختیاری پیش فرض، شامل می شود -h
، به همراه نسخه طولانی آن --help
. این آرگومان با یک پیام راهنما پیش فرض همراه است که آرگومان های پذیرفته شده را توصیف می کند.
کد زیر مقدار اولیه تجزیه کننده را نشان می دهد و خروجی زیر تماس اولیه و به دنبال آن پیام راهنما را نشان می دهد. برخلاف فراخوانیهای پایتون که در مثالهای قبلی استفاده کردیم، به خاطر داشته باشید که از Python 3 با این مثالها استفاده کنید:
import argparse
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
در مرحله بعد، یک توضیحات سفارشی به پیام راهنما برای کاربران خود اضافه می کنیم. مقداردهی اولیه تجزیه کننده به این روش امکان یک متن اضافی را می دهد. کد زیر توضیحات را در قسمت ذخیره می کند text
متغیر، که به صراحت به آن داده شده است argparse
کلاس به عنوان description
پارامتر. با فراخوانی این کد زیر، می توانید ببینید که خروجی به چه شکل است:
import argparse
text = 'This is a test program. It demonstrates how to use the argparse module with a program 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
، که یک آرگومان سبک طولانی متناظر به نام دارد --version
. برای این کار از روش استفاده می کنیم add_argument()
که با سه پارامتر فراخوانی می کنیم (نمایش داده شده برای --version
، فقط):
- نام پارامتر:
--version
- متن راهنما برای پارامتر:
help="show program version"
- اقدام (بدون مقدار اضافی):
action="store_true"
کد منبع برای آن در زیر نمایش داده شده است. خواندن آرگومان ها در متغیر فراخوانی شده args
از طریق انجام می شود parse_args()
روش از parser
هدف - شی. توجه داشته باشید که هم نسخه کوتاه و هم نسخه طولانی را در یک تماس ارسال می کنید. در نهایت، شما بررسی می کنید که آیا ویژگی ها args.V
or args.version
تنظیم می شوند و پیام نسخه را خروجی می دهند:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-V", "--version", help="show program version", action="store_true")
args = parser.parse_args()
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
La --version
آرگومان نیازی به دادن مقدار در خط فرمان ندارد. به همین دلیل است که ما آرگومان عمل را روی آن قرار دادیم "store_true"
. در موارد دیگر ممکن است به یک مقدار اختصاص داده شده اضافی نیاز داشته باشید، برای مثال اگر حجم، ارتفاع یا عرض خاصی را مشخص کنید. این در مثال بعدی نشان داده شده است. به عنوان یک حالت پیش فرض، لطفاً توجه داشته باشید که همه آرگومان ها به صورت رشته تفسیر می شوند:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--width", "-w", help="set output width")
args = parser.parse_args()
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
ماژول getopt
همانطور که ممکن است قبلا متوجه شده باشید، sys
ماژول رشته خط فرمان را فقط به چند وجه تقسیم می کند. پایتون ماژول getopt کمی جلوتر می رود و جداسازی رشته ورودی را با اعتبارسنجی پارامتر گسترش می دهد. بر اساس getopt
تابع C، هم گزینه های کوتاه و هم طولانی، از جمله تخصیص مقدار را امکان پذیر می کند.
در عمل مستلزم این است sys
ماژول برای پردازش صحیح داده های ورودی برای انجام این کار، هر دو sys
ماژول و getopt
ماژول باید از قبل بارگذاری شود. سپس، از لیست پارامترهای ورودی، اولین عنصر لیست را حذف می کنیم (به کد زیر مراجعه کنید)، و لیست باقی مانده از آرگومان های خط فرمان را در متغیری به نام ذخیره می کنیم. argument_list
:
import getopt, sys
full_cmd_arguments = sys.argv
argument_list = full_cmd_arguments[1:]
print argument_list
استدلال ها در argument_list
اکنون می توان با استفاده از getopts()
روش. اما قبل از انجام این کار، باید بگوییم getopts()
در مورد کدام پارامتر معتبر است. آنها به این صورت تعریف می شوند:
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
گزینه کوتاه با کولون پیش رفت، :
. این می گوید getopt
که به این گزینه باید مقداری نسبت داده شود.
این اکنون به ما امکان می دهد لیستی از آرگومان ها را پردازش کنیم. این getopt()
روش نیاز به پیکربندی سه پارامتر دارد - لیست آرگومان های واقعی از argv
، و همچنین گزینه های کوتاه و بلند معتبر (در قطعه کد قبلی نشان داده شده است).
فراخوانی متد خود در یک عبارت try-catch نگهداری می شود تا خطاها را در طول ارزیابی پوشش دهد. اگر آرگومان کشف شود که بخشی از لیستی که قبلاً تعریف شده نیست، یک استثنا مطرح می شود. اسکریپت پایتون پیام خطا را روی صفحه چاپ می کند و با کد خطای 2 خارج می شود:
try:
arguments, values = getopt.getopt(argument_list, short_options, long_options)
except getopt.error as err:
print (str(err))
sys.exit(2)
در نهایت، آرگومان ها با مقادیر مربوطه در دو متغیر نامگذاری شده ذخیره می شوند arguments
و values
. اکنون می توانید به راحتی این متغیرها را در کد خود ارزیابی کنید. می توانیم از a استفاده کنیم for
-حلقه برای تکرار در لیست آرگومان های شناخته شده، یک ورودی پس از ورودی بعدی.
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
به عنوان یک گزینه، که نامعتبر است.
نتیجه
در این مقاله روشهای مختلفی را برای بازیابی آرگومانهای خط فرمان در پایتون نشان دادیم، از جمله استفاده از آن sys
, getopt
و argparse
. این ماژول ها از نظر عملکرد متفاوت هستند، برخی از آنها بسیار بیشتر از بقیه هستند. sys
کاملاً انعطاف پذیر است، در حالی که هر دو getopt
و argparse
نیاز به ساختار در مقابل، آنها بیشتر کارهای پیچیده را پوشش می دهند sys
به شما واگذار می شود پس از کار بر روی مثال های ارائه شده، باید بتوانید تعیین کنید که کدام ماژول برای پروژه شما مناسب تر است.
در این مقاله ما در مورد راه حل های دیگری مانند این صحبت نکردیم docopts
ماژول، ما فقط به آن اشاره کردیم. این ماژول رویکرد کاملا متفاوتی را دنبال می کند و در یکی از مقالات بعدی به تفصیل توضیح داده خواهد شد.