آرگومان های خط فرمان در پایتون

بررسی اجمالی

از آنجایی که پایتون یک زبان برنامه نویسی بسیار محبوب است، و همچنین پشتیبانی از اکثر سیستم عامل ها و بسیاری از کتابخانه ها که پردازش آرگومان خط فرمان را آسان می کند – به طور گسترده برای ایجاد ابزارهای خط فرمان برای اهداف مختلف استفاده می شود. این ابزارها می‌توانند از برنامه‌های ساده 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 ماژول، ما فقط به آن اشاره کردیم. این ماژول رویکرد کاملا متفاوتی را دنبال می کند و در یکی از مقالات بعدی به تفصیل توضیح داده خواهد شد.

منابع

تمبر زمان:

بیشتر از Stackabuse