optparse --- پارسر گزینه‌های خط فرمان

کد منبع: Lib/optparse.py


انتخاب یک کتابخانه تجزیه آرگومان

کتابخانه استاندارد شامل ۳ کتابخانه تجزیه آرگومان است:

  • getopt: ماژولی که API رویه‌ای getopt در زبان C را به‌دقت بازتاب می‌دهد. از پیش از نخستین انتشار Python 1.0 در کتابخانه استاندارد گنجانده شده است.

  • optparse: جایگزینی اعلانی برای getopt که قابلیت معادلی را بدون نیاز به اینکه هر برنامه منطق تجزیه گزینه‌های خود را به‌صورت رویه‌ای پیاده‌سازی کند، فراهم می‌کند. از نسخه Python 2.3 در کتابخانه استاندارد گنجانده شده است.

  • argparse: جایگزینی سخت‌گیرانه‌تر برای optparse که به‌طور پیش‌فرض قابلیت‌های بیشتری فراهم می‌کند، اما به بهای کاهش انعطاف‌پذیری برنامه در کنترل دقیق چگونگی پردازش آرگومان‌ها. از زمان انتشار Python 2.7 و Python 3.2 در کتابخانه استاندارد گنجانده شده است.

در نبود محدودیت‌های طراحی خاص‌تر برای تجزیه آرگومان، argparse گزینه توصیه‌شده برای پیاده‌سازی برنامه‌های خط فرمان است، زیرا بالاترین سطح از قابلیت‌های پایه را با کمترین کد در سطح برنامه ارائه می‌دهد.

getopt تقریباً به‌طور کامل به دلایل سازگاری با نسخه‌های پیشین حفظ شده است. با این حال، این ماژول همچنین کاربرد خاصی به‌عنوان ابزاری برای نمونه‌سازی و آزمون مدیریت آرگومان‌های خط فرمان در برنامه‌های کاربردی C مبتنی بر getopt دارد.

در موارد زیر، optparse باید به‌عنوان جایگزینی برای argparse در نظر گرفته شود:

  • یک برنامه کاربردی از قبل از optparse استفاده می‌کند و نمی‌خواهد خطر تغییرات رفتاری ظریفی را که ممکن است هنگام مهاجرت به argparse پیش بیایند، بپذیرد

  • برنامه به کنترل بیشتری بر نحوه‌ی در هم آمیخته شدن گزینه‌ها و پارامترهای جایگاهی در خط فرمان نیاز دارد (از جمله توانایی غیرفعال کردن کامل قابلیت در هم آمیختن)

  • برنامه کاربردی به کنترل بیشتری بر تجزیه تدریجی عناصر خط فرمان نیاز دارد (اگرچه argparse از این قابلیت پشتیبانی می‌کند، اما شیوه دقیق عملکرد آن در عمل برای برخی موارد استفاده نامطلوب است)

  • برنامه به کنترل بیشتری بر پردازش گزینه‌هایی نیاز دارد که مقادیر پارامترهایی را می‌پذیرند که ممکن است با - شروع شوند (مانند گزینه‌های واگذاری‌شده برای ارسال به زیرفرآیندهای فراخوانی‌شده)

  • برنامه کاربردی به رفتار دیگری برای پردازش پارامترهای خط فرمان نیاز دارد که argparse از آن پشتیبانی نمی‌کند، اما می‌توان آن را بر اساس رابط سطح پایین‌تر ارائه‌شده توسط optparse پیاده‌سازی کرد

این ملاحظات همچنین به این معناست که optparse احتمالاً پایه بهتری برای نویسندگان کتابخانه‌ها که کتابخانه‌های پردازش آرگومان‌های خط فرمان شخص ثالث را می‌نویسند، فراهم می‌کند.

به‌عنوان مثالی ملموس، دو پیکربندی تجزیه‌ی آرگومان‌های خط فرمان زیر را در نظر بگیرید، که اولی از optparse و دومی از argparse استفاده می‌کند:

import optparse

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option('-o', '--output')
    parser.add_option('-v', dest='verbose', action='store_true')
    opts, args = parser.parse_args()
    process(args, output=opts.output, verbose=opts.verbose)
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--output')
    parser.add_argument('-v', dest='verbose', action='store_true')
    parser.add_argument('rest', nargs='*')
    args = parser.parse_args()
    process(args.rest, output=args.output, verbose=args.verbose)

واضح‌ترین تفاوت این است که در نسخه‌ی optparse، آرگومان‌های غیرگزینه‌ای پس از تکمیل پردازش گزینه‌ها، به‌طور جداگانه توسط برنامه پردازش می‌شوند. در نسخه‌ی argparse، آرگومان‌های جایگاهی به همان شیوه‌ی گزینه‌های نام‌دار تعریف و پردازش می‌شوند.

با این حال، نسخه‌ی argparse برخی ترکیب‌های پارامتر را نیز متفاوت از شیوه‌ای که نسخه‌ی optparse آن‌ها را مدیریت می‌کرد، مدیریت خواهد کرد. برای مثال (از جمله تفاوت‌های دیگر):

  • ارائه‌ی -o -v هنگام استفاده از optparse، output="-v" و verbose=False را به‌دست می‌دهد، اما در argparse یک خطای کاربرد ایجاد می‌کند (با این اعتراض که هیچ مقداری برای -o/--output ارائه نشده است، زیرا -v به‌عنوان پرچم سطح جزئیات تفسیر می‌شود)

  • به‌طور مشابه، ارائه -o -- هنگام استفاده از optparse، output="--" و args=() را می‌دهد، اما در argparse یک خطای کاربرد ایجاد می‌کند (همچنین اعلام می‌کند که هیچ مقداری برای -o/--output ارائه نشده است، زیرا -- به‌عنوان پایان پردازش گزینه‌ها تفسیر می‌شود و تمام مقادیر باقی‌مانده به‌عنوان آرگومان‌های جایگاهی در نظر گرفته می‌شوند)

  • وارد کردن -o=foo هنگام استفاده از optparse مقدار output="=foo" را می‌دهد، اما با argparse مقدار output="foo" را می‌دهد (زیرا = به‌عنوان یک جداکننده جایگزین برای مقدارهای پارامتر گزینه، یک حالت خاص محسوب می‌شود).

این‌که این رفتارهای متفاوت در نسخه‌ی argparse مطلوب یا مشکل تلقی شوند، به مورد استفاده خاص برنامه خط فرمان بستگی دارد.

همچنین ملاحظه نمائید

click یک کتابخانه شخص ثالث برای پردازش آرگومان است (در ابتدا مبتنی بر optparse)، که امکان توسعه برنامه‌های خط فرمان را به‌صورت مجموعه‌ای از توابع دکوراتورشده پیاده‌سازی دستور فراهم می‌کند.

سایر کتابخانه‌های شخص ثالث، مانند typer یا msgspec-click، به شما امکان می‌دهند رابط‌های خط فرمان را به شیوه‌هایی مشخص کنید که به‌طور مؤثرتری با بررسی ایستای حاشیه‌نویسی‌های نوع پایتون یکپارچه می‌شوند.

مقدمه

optparse کتابخانه‌ای آسان‌تر، انعطاف‌پذیرتر و قدرتمندتر برای تجزیه‌ی گزینه‌های خط فرمان نسبت به ماژول کمینه‌گرای getopt است. optparse از سبک اعلامی‌تری برای تجزیه‌ی خط فرمان استفاده می‌کند: شما یک نمونه از OptionParser ایجاد می‌کنید، آن را با گزینه‌ها پر می‌کنید و خط فرمان را تجزیه می‌کنید. optparse به کاربران اجازه می‌دهد گزینه‌ها را با سینتکس مرسوم GNU/POSIX مشخص کنند و علاوه بر این، پیام‌های کاربرد و راهنمایی را برای شما تولید می‌کند.

در اینجا مثالی از استفاده از optparse در یک اسکریپت ساده آمده است:

from optparse import OptionParser
...
parser = OptionParser()
parser.add_option("-f", "--file", dest="filename",
                  help="write report to FILE", metavar="FILE")
parser.add_option("-q", "--quiet",
                  action="store_false", dest="verbose", default=True,
                  help="don't print status messages to stdout")

(options, args) = parser.parse_args()

با این چند خط کد، کاربران اسکریپت شما اکنون می‌توانند «کار معمول» را در خط فرمان انجام دهند، برای مثال:

<yourscript> --file=outfile -q

هنگامی که optparse خط فرمان را تجزیه می‌کند، ویژگی‌های شیء options برگردانده‌شده توسط parse_args() را بر اساس مقادیر خط فرمان ارائه‌شده توسط کاربر تنظیم می‌کند. هنگام بازگشت parse_args() از تجزیه این خط فرمان، options.filename برابر "outfile" و options.verbose برابر False خواهد بود. optparse هم از گزینه‌های بلند و هم از گزینه‌های کوتاه پشتیبانی می‌کند، اجازه می‌دهد گزینه‌های کوتاه با یکدیگر ادغام شوند، و اجازه می‌دهد گزینه‌ها به روش‌های گوناگونی با آرگومان‌های خود مرتبط شوند. بنابراین، سطرهای فرمان زیر همگی معادل مثال بالا هستند:

<yourscript> -f outfile --quiet
<yourscript> --quiet --file outfile
<yourscript> -q -foutfile
<yourscript> -qfoutfile

علاوه بر این، کاربران می‌توانند یکی از موارد زیر را اجرا کنند

<yourscript> -h
<yourscript> --help

و optparse خلاصه‌ای کوتاه از گزینه‌های اسکریپت شما را نمایش خواهد داد:

کاربرد: <yourscript> [options]

گزینه‌ها:
  -h, --help            این پیام راهنما را نمایش می‌دهد و خارج می‌شود
  -f FILE, --file=FILE  گزارش را در FILE می‌نویسد
  -q, --quiet           پیام‌های وضعیت را در stdout چاپ نمی‌کند

که مقدار yourscript در ران‌تایم تعیین می‌شود (معمولاً از sys.argv[0]).

پیش‌زمینه

optparse به‌صراحت طراحی شده است تا ایجاد برنامه‌هایی با رابط‌های خط فرمان ساده را تشویق کند که از قراردادهای تعیین‌شده توسط خانواده‌ی توابع getopt() در دسترس توسعه‌دهندگان C پیروی می‌کنند. برای همین منظور، این ماژول فقط از رایج‌ترین سینتکس و معناشناسی خط فرمان پشتیبانی می‌کند که به‌طور قراردادی در یونیکس استفاده می‌شود. اگر با این قراردادها آشنا نیستید، خواندن این بخش به شما امکان می‌دهد با آن‌ها آشنا شوید.

اصطلاحات

آرگومان

رشته‌ای که در خط فرمان وارد می‌شود و از سوی پوسته به execl() یا execv() پاس داده می‌شود. در پایتون، آرگومان‌ها عناصر sys.argv[1:] هستند (sys.argv[0] نام برنامه‌ای است که اجرا می‌شود). پوسته‌های یونیکس همچنین از اصطلاح «word» استفاده می‌کنند.

گاهی جایگزین‌کردن فهرستی از آرگومان‌ها غیر از sys.argv[1:] مطلوب است، بنابراین باید «آرگومان» را به‌عنوان «عنصری از sys.argv[1:]، یا از فهرست دیگری که به‌عنوان جایگزینی برای sys.argv[1:] فراهم شده است» بخوانید.

گزینه

آرگومانی که برای ارائه اطلاعات اضافی به‌منظور هدایت یا سفارشی‌سازی اجرای یک برنامه استفاده می‌شود. سینتکس‌های مختلفی برای گزینه‌ها وجود دارد؛ سینتکس سنتی یونیکس یک خط تیره («-») است که پس از آن یک نویسه می‌آید، برای مثال -x یا -F. همچنین، سینتکس سنتی یونیکس اجازه می‌دهد چند گزینه در یک آرگومان واحد ادغام شوند، برای مثال -x -F معادل -xF است. پروژه‌ی گنو -- را معرفی کرد که پس از آن دنباله‌ای از کلمه‌های جداشده با خط تیره می‌آید، برای مثال --file یا --dry-run. این‌ها تنها دو سینتکس گزینه هستند که توسط optparse ارائه می‌شوند.

برخی دیگر از سینتکس‌های گزینه‌ها که دنیا به خود دیده است عبارت‌اند از:

  • یک خط تیره و پس از آن چند حرف، برای مثال -pf (این با چند گزینه که در یک آرگومان واحد ادغام شده‌اند، یکسان نیست)

  • یک خط تیره که پس از آن یک کلمه کامل بیاید، مثلاً -file (این از نظر فنی معادل سینتکس قبلی است، اما این دو معمولاً در یک برنامه دیده نمی‌شوند)

  • یک علامت مثبت به‌همراه یک حرف، یا چند حرف، یا یک کلمه، مثلاً +f، +rgb

  • یک اسلش که پس از آن یک حرف، یا چند حرف، یا یک کلمه بیاید، برای مثال /f، /file

این سینتکس‌های گزینه توسط optparse پشتیبانی نمی‌شوند و هرگز پشتیبانی نخواهند شد. این موضوع عمدی است: سه مورد نخست در هیچ محیطی استاندارد نیستند و آخرین مورد تنها زمانی منطقی است که منحصراً ویندوز یا برخی سکوهای قدیمی (مانند VMS، MS-DOS) را هدف قرار داده باشید.

آرگومان گزینه

آرگومانی که به‌دنبال یک گزینه می‌آید، ارتباط نزدیکی با آن گزینه دارد و هنگامی که آن گزینه مصرف می‌شود، از فهرست آرگومان‌ها برداشته می‌شود. با optparse، آرگومان‌های گزینه ممکن است در آرگومانی جداگانه از گزینه‌ی خود باشند:

-f foo
--file foo

یا در همان آرگومان گنجانده شود:

-ffoo
--file=foo

معمولاً یک گزینه مشخص یا آرگومان می‌گیرد یا نمی‌گیرد. بسیاری از افراد قابلیت «آرگومان‌های اختیاری گزینه‌ها» را می‌خواهند، به این معنا که برخی گزینه‌ها اگر آرگومانی ببینند آن را می‌گیرند و اگر نبینند نمی‌گیرند. این موضوع تا حدی بحث‌برانگیز است، زیرا باعث مبهم شدن تجزیه می‌شود: اگر -a آرگومان اختیاری بگیرد و -b گزینه‌ای کاملاً متفاوت باشد، -ab را چگونه تفسیر می‌کنیم؟ به دلیل همین ابهام، optparse این قابلیت را پشتیبانی نمی‌کند.

آرگومان جایگاهی

چیزی باقی‌مانده در فهرست آرگومان‌ها پس از تجزیه گزینه‌ها، یعنی پس از تجزیه گزینه‌ها و آرگومان‌هایشان و حذف آن‌ها از فهرست آرگومان‌ها.

گزینه‌ی ضروری

گزینه‌ای که باید در خط فرمان ارائه شود؛ توجه داشته باشید که عبارت «required option» در زبان انگلیسی متناقض است. optparse شما را از پیاده‌سازی گزینه‌های الزامی بازنمی‌دارد، اما کمک زیادی هم در این زمینه به شما نمی‌کند.

برای مثال، این خط فرمان فرضی را در نظر بگیرید:

prog -v --report report.txt foo bar

-v و --report هر دو گزینه هستند. با فرض اینکه --report یک آرگومان می‌گیرد، report.txt آرگومانِ گزینه است. foo و bar آرگومان‌های جایگاهی هستند.

گزینه‌ها برای چه منظوری هستند؟

گزینه‌ها برای ارائه‌ی اطلاعات اضافی جهت تنظیم یا سفارشی‌سازی اجرای یک برنامه استفاده می‌شوند. در صورتی که واضح نبود، گزینه‌ها معمولاً اختیاری هستند. یک برنامه باید بتواند بدون حتی یک گزینه نیز به‌خوبی اجرا شود. (برنامه‌ای تصادفی از مجموعه‌ابزارهای Unix یا GNU انتخاب کنید. آیا می‌تواند بدون هیچ گزینه‌ای اجرا شود و همچنان معنادار باشد؟ استثناهای اصلی find، tar و dd---که همه‌ی آن‌ها عجیب‌وغریب‌های جهش‌یافته‌ای هستند که به‌حق به‌دلیل سینتکس غیراستاندارد و رابط‌های گیج‌کننده‌شان مورد انتقاد قرار گرفته‌اند.)

بسیاری از افراد می‌خواهند برنامه‌هایشان «گزینه‌های اجباری» داشته باشند. به این موضوع فکر کنید. اگر چیزی اجباری است، پس اختیاری نیست! اگر اطلاعاتی وجود دارد که برنامه‌ی شما برای اجرای موفق به‌طور قطع به آن نیاز دارد، آرگومان‌های جایگاهی برای همین منظور هستند.

به‌عنوان نمونه‌ای از طراحی خوب رابط خط فرمان، ابزار ساده cp را برای کپی کردن پرونده‌ها در نظر بگیرید. تلاش برای کپی کردن پرونده‌ها بدون مشخص کردن مقصد و حداقل یک منبع چندان منطقی نیست. بنابراین، اگر cp را بدون هیچ آرگومانی اجرا کنید، با شکست مواجه می‌شود. با این حال، این ابزار دارای سینتکس انعطاف‌پذیر و مفیدی است که اصلاً به هیچ گزینه‌ای نیاز ندارد:

cp SOURCE DEST
cp SOURCE ... DEST-DIR

فقط با همان می‌توانید تا حد زیادی پیش بروید. بیشتر پیاده‌سازی‌های cp گزینه‌های زیادی را برای تنظیم دقیق نحوه‌ی کپی‌شدن پرونده‌ها فراهم می‌کنند: می‌توانید حالت و زمان تغییر را حفظ کنید، از دنبال کردن پیوندهای نمادین خودداری کنید، پیش از بازنویسی پرونده‌های موجود تأیید بخواهید و غیره. اما هیچ‌کدام از این موارد توجه را از مأموریت اصلی cp منحرف نمی‌کند؛ یعنی کپی کردن یک پرونده به پرونده‌ای دیگر، یا چند پرونده به پوشه‌ای دیگر.

آرگومان‌های جایگاهی برای چه کاربردی دارند؟

آرگومان‌های جایگاهی برای آن دسته از اطلاعاتی هستند که برنامه شما قطعاً و یقیناً برای اجرا به آن‌ها نیاز دارد.

یک رابط کاربری خوب باید تا حد ممکن نیازمندی‌های مطلق کمی داشته باشد. اگر برنامه شما برای اجرای موفقیت‌آمیز به ۱۷ مورد اطلاعات مجزا نیاز داشته باشد، چگونگی دریافت آن اطلاعات از کاربر چندان اهمیتی ندارد---بیشتر افراد پیش از آنکه برنامه را با موفقیت اجرا کنند، تسلیم می‌شوند و آن را ترک می‌کنند. این موضوع چه رابط کاربری خط فرمان باشد، چه پرونده پیکربندی و چه GUI صدق می‌کند: اگر این‌قدر از کاربران خود درخواست داشته باشید، بیشتر آن‌ها به‌سادگی تسلیم خواهند شد.

به‌طور خلاصه، سعی کنید میزان اطلاعاتی را که کاربران قطعاً ملزم به ارائه آن هستند به حداقل برسانید—هر جا که ممکن است از پیش‌فرض‌های مناسب استفاده کنید. البته، شما همچنین می‌خواهید برنامه‌های شما به‌طور معقولی انعطاف‌پذیر باشند. گزینه‌ها برای همین منظور هستند. باز هم، فرقی نمی‌کند که آن‌ها ورودی‌هایی در یک پرونده پیکربندی باشند، ابزارک‌هایی در پنجره‌ی «Preferences» یک GUI، یا گزینه‌های خط فرمان—هرچه گزینه‌های بیشتری را پیاده‌سازی کنید، برنامه‌ی شما انعطاف‌پذیرتر می‌شود و پیاده‌سازی آن پیچیده‌تر می‌گردد. البته انعطاف‌پذیری بیش‌ازحد هم معایبی دارد؛ گزینه‌های بیش‌ازحد می‌توانند کاربران را سردرگم کنند و نگهداری کد شما را بسیار سخت‌تر کنند.

آموزش

اگرچه optparse بسیار انعطاف‌پذیر و قدرتمند است، اما استفاده از آن در بیشتر موارد ساده است. این بخش الگوهای کد رایج در هر برنامه‌ی مبتنی بر optparse را پوشش می‌دهد.

ابتدا باید کلاس OptionParser را ایمپورت کنید؛ سپس در ابتدای برنامه اصلی، یک نمونه از OptionParser ایجاد کنید:

from optparse import OptionParser
...
parser = OptionParser()

سپس می‌توانید تعریف گزینه‌ها را آغاز کنید. سینتکس پایه به این صورت است:

parser.add_option(opt_str, ...,
                  attr=value, ...)

هر گزینه یک یا چند رشته‌ی گزینه، مانند -f یا --file، و چندین ویژگی گزینه دارد که به optparse می‌گویند چه چیزی را باید انتظار داشته باشد و وقتی با آن گزینه در خط فرمان مواجه می‌شود چه کاری باید انجام دهد.

معمولاً هر گزینه دارای یک رشته‌ی گزینه‌ی کوتاه و یک رشته‌ی گزینه‌ی بلند است، برای مثال:

parser.add_option("-f", "--file", ...)

شما آزادید هر تعداد رشته‌ی گزینه کوتاه و هر تعداد رشته‌ی گزینه بلند که بخواهید تعریف کنید (از جمله صفر)، به شرطی که در مجموع دست‌کم یک رشته‌ی گزینه وجود داشته باشد.

رشته‌های گزینه‌ای که به OptionParser.add_option() داده می‌شوند، در عمل برچسب‌هایی برای گزینه‌ای هستند که با آن فراخوانی تعریف می‌شود. برای اختصار، ما اغلب به برخورد با یک گزینه در خط فرمان اشاره خواهیم کرد؛ در واقع، optparse با رشته‌های گزینه برخورد می‌کند و گزینه‌ها را از آن‌ها جست‌وجو می‌کند.

پس از این‌که همه‌ی گزینه‌های شما تعریف شدند، به optparse دستور دهید خط فرمان برنامه‌تان را تجزیه کند:

(options, args) = parser.parse_args()

(در صورت تمایل، می‌توانید فهرستی سفارشی از آرگومان‌ها را به parse_args() بدهید، اما این کار به‌ندرت ضروری است: به‌طور پیش‌فرض از sys.argv[1:] استفاده می‌کند.)

parse_args() دو مقدار بازمی‌گرداند:

  • options، شیءای حاوی مقادیر همه‌ی گزینه‌های شما—برای مثال اگر --file یک آرگومان رشته‌ای می‌گیرد، آنگاه options.file نام پرونده‌ای خواهد بود که کاربر ارائه کرده است، یا None اگر کاربر آن گزینه را ارائه نکرده باشد

  • args، فهرست آرگومان‌های جایگاهی باقی‌مانده پس از تجزیه گزینه‌ها

این بخش از آموزش تنها چهار مورد از مهم‌ترین ویژگی‌های گزینه را پوشش می‌دهد: action، type، dest (مقصد)، و help. از میان این‌ها، action بنیادی‌ترین است.

درک کنش‌های گزینه

اکشن‌ها به optparse می‌گویند که هنگامی که با گزینه‌ای در خط فرمان مواجه می‌شود، چه کاری انجام دهد. مجموعه‌ای ثابت از اکشن‌ها در optparse به‌صورت سخت‌کد وجود دارد؛ افزودن اکشن‌های جدید موضوعی پیشرفته است که در بخش گسترش optparse پوشش داده شده است. بیشتر اکشن‌ها به optparse می‌گویند که مقداری را در متغیری ذخیره کند—برای مثال، رشته‌ای را از خط فرمان بگیرد و آن را در ویژگی‌ای از options ذخیره کند.

اگر اکشن گزینه‌ای را مشخص نکنید، optparse به‌طور پیش‌فرض از store استفاده می‌کند.

کنش store

رایج‌ترین اکشن گزینه store است، که به optparse می‌گوید آرگومان بعدی (یا باقی‌مانده‌ی آرگومان فعلی) را بگیرد، اطمینان حاصل کند که از نوع صحیح است، و آن را در مقصد انتخابی شما ذخیره کند.

برای مثال:

parser.add_option("-f", "--file",
                  action="store", type="string", dest="filename")

حال بیایید یک خط فرمان جعلی بسازیم و از optparse بخواهیم آن را تجزیه کند:

args = ["-f", "foo.txt"]
(options, args) = parser.parse_args(args)

وقتی optparse رشته‌ی گزینه‌ی -f را می‌بیند، آرگومان بعدی، foo.txt، را مصرف می‌کند و آن را در options.filename ذخیره می‌کند. بنابراین، پس از این فراخوانی parse_args()، options.filename برابر "foo.txt" است.

برخی دیگر از انواع گزینه‌های پشتیبانی‌شده توسط optparse، int و float هستند. در اینجا گزینه‌ای آمده است که انتظار یک آرگومان عدد صحیح را دارد:

parser.add_option("-n", type="int", dest="num")

توجه داشته باشید که این گزینه رشته‌ی گزینه‌ی بلندی ندارد، که کاملاً قابل قبول است. همچنین، هیچ اکشن صریحی وجود ندارد، زیرا پیش‌فرض store است.

بیایید یک خط فرمان جعلی دیگر را تجزیه کنیم. این بار، آرگومان گزینه را دقیقاً به خود گزینه می‌چسبانیم: از آن‌جا که -n42 (یک آرگومان) معادل -n 42 (دو آرگومان) است، کد

(options, args) = parser.parse_args(["-n42"])
print(options.num)

42 را چاپ خواهد کرد.

اگر نوعی را مشخص نکنید، optparse آن را string فرض می‌کند. با توجه به این واقعیت که اکشن پیش‌فرض برابر store است، این بدان معناست که اولین مثال ما می‌تواند بسیار کوتاه‌تر باشد:

parser.add_option("-f", "--file", dest="filename")

اگر مقصدی ارائه نکنید، optparse یک پیش‌فرض مناسب را از رشته‌های گزینه تعیین می‌کند: اگر اولین رشته گزینه بلند --foo-bar باشد، آنگاه مقصد پیش‌فرض foo_bar است. اگر هیچ رشته گزینه بلندی وجود نداشته باشد، optparse اولین رشته گزینه کوتاه را بررسی می‌کند: مقصد پیش‌فرض برای -f برابر f است.

optparse همچنین شامل نوع توکار complex می‌شود. افزودن انواع در بخش گسترش optparse پوشش داده شده است.

مدیریت گزینه‌های بولی (پرچمی)

گزینه‌های پرچمی---که هنگام مشاهده‌ی یک گزینه‌ی خاص، متغیری را روی درست یا نادرست تنظیم می‌کنند---بسیار رایج هستند. optparse از آن‌ها با دو اکشن جداگانه، store_true و store_false پشتیبانی می‌کند. برای مثال، ممکن است یک پرچم verbose داشته باشید که با -v فعال و با -q غیرفعال می‌شود:

parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose")

در اینجا دو گزینه متفاوت با یک مقصد یکسان داریم که کاملاً قابل قبول است. (این فقط به این معناست که هنگام تنظیم مقادیر پیش‌فرض باید کمی دقت کنید—در زیر ببینید.)

هنگامی که optparse با -v در خط فرمان مواجه می‌شود، options.verbose را روی True تنظیم می‌کند؛ هنگامی که با -q مواجه می‌شود، options.verbose روی False تنظیم می‌شود.

سایر اکشن‌ها

برخی دیگر از کنش‌های پشتیبانی‌شده توسط optparse عبارتند از:

"store_const"

ذخیره‌ی یک مقدار ثابت، از پیش تنظیم‌شده از طریق Option.const

"append"

افزودن آرگومان این گزینه به یک فهرست

"count"

یک شمارنده را یک واحد افزایش دهید

"callback"

فراخوانی یک تابع مشخص

این موارد در بخش راهنمای مرجع و بخش کال‌بک‌های گزینه پوشش داده شده‌اند.

مقادیر پیش‌فرض

همه‌ی مثال‌های بالا شامل تنظیم یک متغیر (همان «مقصد») هنگامی است که گزینه‌های خاصی در خط فرمان دیده شوند. اگر آن گزینه‌ها هرگز دیده نشوند، چه اتفاقی می‌افتد؟ از آن‌جا که هیچ مقدار پیش‌فرضی ارائه نکرده‌ایم، همه‌ی آن‌ها روی None تنظیم می‌شوند. این معمولاً مشکلی ندارد، اما گاهی کنترل بیشتری می‌خواهید. optparse به شما امکان می‌دهد برای هر مقصد یک مقدار پیش‌فرض ارائه دهید، که پیش از تجزیه‌ی خط فرمان اختصاص می‌یابد.

نخست، مثال verbose/quiet را در نظر بگیرید. اگر بخواهیم optparse مقدار verbose را روی True تنظیم کند، مگر آنکه -q مشاهده شود، می‌توانیم این کار را انجام دهیم:

parser.add_option("-v", action="store_true", dest="verbose", default=True)
parser.add_option("-q", action="store_false", dest="verbose")

از آنجا که مقادیر پیش‌فرض به مقصد اعمال می‌شوند، نه به یک گزینه خاص، و این دو گزینه اتفاقاً مقصد یکسانی دارند، این دقیقاً معادل است:

parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose", default=True)

این را در نظر بگیرید:

parser.add_option("-v", action="store_true", dest="verbose", default=False)
parser.add_option("-q", action="store_false", dest="verbose", default=True)

باز هم، مقدار پیش‌فرض برای verbose برابر True خواهد بود: آخرین مقدار پیش‌فرض ارائه‌شده برای هر مقصد مشخص، همان مقداری است که معتبر است.

راه روشن‌تر برای تعیین مقادیر پیش‌فرض، متد set_defaults() از OptionParser است که می‌توانید آن را در هر زمانی پیش از فراخوانی parse_args() فراخوانی کنید:

parser.set_defaults(verbose=True)
parser.add_option(...)
(options, args) = parser.parse_args()

مانند قبل، آخرین مقدار تعیین‌شده برای یک مقصد گزینه‌ی مشخص، مقداری است که معتبر است. برای شفافیت، سعی کنید برای تنظیم مقادیر پیش‌فرض فقط از یکی از دو روش استفاده کنید، نه از هر دو.

تولید راهنما

توانایی optparse در تولید خودکار متن راهنما و طرز استفاده، برای ایجاد رابط‌های خط فرمان کاربرپسند مفید است. کافی است یک مقدار help برای هر گزینه ارائه دهید و به‌اختیار، یک پیام کوتاه طرز استفاده برای کل برنامه‌تان قرار دهید. در اینجا یک OptionParser حاوی گزینه‌های کاربرپسند (مستندسازی‌شده) آمده است:

usage = "usage: %prog [options] arg1 arg2"
parser = OptionParser(usage=usage)
parser.add_option("-v", "--verbose",
                  action="store_true", dest="verbose", default=True,
                  help="make lots of noise [default]")
parser.add_option("-q", "--quiet",
                  action="store_false", dest="verbose",
                  help="be vewwy quiet (I'm hunting wabbits)")
parser.add_option("-f", "--filename",
                  metavar="FILE", help="write output to FILE")
parser.add_option("-m", "--mode",
                  default="intermediate",
                  help="interaction mode: novice, intermediate, "
                       "or expert [default: %default]")

اگر optparse با -h یا --help در خط فرمان مواجه شود، یا اگر فقط parser.print_help() را فراخوانی کنید، موارد زیر را در خروجی استاندارد چاپ می‌کند:

طرز استفاده: <yourscript> [options] arg1 arg2

گزینه‌ها:
  -h, --help            نمایش این پیام راهنما و خروج
  -v, --verbose         سروصدای زیاد [پیش‌فرض]
  -q, --quiet           سکوت بسیار (من در حال شکار خرگوش‌ها هستم)
  -f FILE, --filename=FILE
                        نوشتن خروجی در FILE
  -m MODE, --mode=MODE  حالت تعامل: novice، intermediate یا
                        expert [پیش‌فرض: intermediate]

(اگر خروجی راهنما توسط یک گزینه‌ی راهنما فعال شود، optparse پس از چاپ متن راهنما خارج می‌شود.)

در اینجا موارد زیادی وجود دارد که به optparse کمک می‌کند تا بهترین پیام راهنمای ممکن را تولید کند:

  • اسکریپت پیام کاربرد خود را تعریف می‌کند:

    usage = "usage: %prog [options] arg1 arg2"
    

    optparse مقدار %prog را در رشته‌ی کاربرد به نام برنامه‌ی جاری، یعنی os.path.basename(sys.argv[0])، بسط می‌دهد. سپس رشته‌ی بسط‌یافته پیش از راهنمای دقیق گزینه‌ها چاپ می‌شود.

    اگر رشته‌ی کاربرد را ارائه نکنید، optparse از یک پیش‌فرض ساده اما معقول استفاده می‌کند: "Usage: %prog [options]"، که اگر اسکریپت شما هیچ آرگومان جایگاهی دریافت نمی‌کند، مناسب است.

  • هر گزینه یک رشته‌ی راهنما تعریف می‌کند و نگران شکستن سطرها نیست---optparse شکستن سطرها و زیبا کردن خروجی راهنما را بر عهده می‌گیرد.

  • گزینه‌هایی که یک مقدار می‌پذیرند، این موضوع را در پیام راهنمای تولیدشده به‌صورت خودکار نشان می‌دهند، برای مثال برای گزینه "mode":

    -m MODE, --mode=MODE
    

    در اینجا، به «MODE» فرامتغیر گفته می‌شود: این نشان‌دهنده‌ی آرگومانی است که انتظار می‌رود کاربر به -m/--mode بدهد. به‌طور پیش‌فرض، optparse نام متغیر مقصد را به حروف بزرگ تبدیل می‌کند و از آن برای فرامتغیر استفاده می‌کند. گاهی، این آن چیزی نیست که شما می‌خواهید—برای مثال، گزینه‌ی --filename به‌صراحت metavar="FILE" را تنظیم می‌کند و منجر به این توضیح گزینه‌ی تولیدشده به‌صورت خودکار می‌شود:

    -f FILE, --filename=FILE
    

    البته این موضوع فقط برای صرفه‌جویی در فضا مهم نیست: متن راهنمای نوشته‌شده به‌صورت دستی از متغیر متا (meta-variable) FILE استفاده می‌کند تا کاربر را از وجود ارتباط میان سینتکس نیمه‌رسمی -f FILE و توصیف معنایی غیررسمی «خروجی را در FILE بنویسید» آگاه کند. این راهی ساده اما مؤثر است که متن راهنمای شما را برای کاربران نهایی بسیار واضح‌تر و مفیدتر می‌کند.

  • گزینه‌هایی که مقدار پیش‌فرض دارند می‌توانند شامل %default در رشته‌ی راهنما باشند---optparse آن را با str() مقدار پیش‌فرض گزینه جایگزین می‌کند. اگر گزینه‌ای مقدار پیش‌فرض نداشته باشد (یا مقدار پیش‌فرض آن None باشد)، %default به none گسترش می‌یابد.

گروه‌بندی گزینه‌ها

هنگام کار با گزینه‌های زیاد، گروه‌بندی این گزینه‌ها برای خروجی راهنمای بهتر مناسب است. یک OptionParser می‌تواند شامل چندین گروه گزینه باشد، که هر یک می‌تواند شامل چندین گزینه باشد.

یک گروه گزینه با استفاده از کلاس OptionGroup به دست می‌آید:

class optparse.OptionGroup(parser, title, description=None)

که در آن

  • parser نمونه‌ای از OptionParser است که گروه در آن درج خواهد شد

  • title عنوان گروه است

  • description، اختیاری، شرح بلندی از گروه است

OptionGroup از OptionContainer ارث می‌برد (مانند OptionParser) و بنابراین می‌توان از متد add_option() برای افزودن یک گزینه به گروه استفاده کرد.

پس از تعریف همه‌ی گزینه‌ها، گروه با استفاده از متد add_option_group() از کلاس OptionParser به پارسری که پیش‌تر تعریف شده است اضافه می‌شود.

با ادامه‌ی کار با پارسر تعریف‌شده در بخش پیشین، افزودن یک OptionGroup به پارسر آسان است:

group = OptionGroup(parser, "Dangerous Options",
                    "Caution: use these options at your own risk.  "
                    "It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)

این منجر به خروجی help زیر می‌شود:

طرز استفاده: <yourscript> [options] arg1 arg2

گزینه‌ها:
  -h, --help            نمایش این پیام راهنما و خروج
  -v, --verbose         ایجاد سروصدای زیاد [پیش‌فرض]
  -q, --quiet           بسیار ساکت باشید (من در حال شکار خرگوش‌ها هستم)
  -f FILE, --filename=FILE
                        نوشتن خروجی در FILE
  -m MODE, --mode=MODE  حالت تعامل: novice، intermediate یا
                        expert [پیش‌فرض: intermediate]

  گزینه‌های خطرناک:
    احتیاط: از این گزینه‌ها با مسئولیت خودتان استفاده کنید. تصور می‌شود برخی
    از آن‌ها گاز بگیرند.

    -g                  گزینه گروهی.

یک مثال کمی کامل‌تر ممکن است شامل استفاده از بیش از یک گروه باشد: همچنان مثال قبلی را گسترش می‌دهیم:

group = OptionGroup(parser, "Dangerous Options",
                    "Caution: use these options at your own risk.  "
                    "It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)

group = OptionGroup(parser, "Debug Options")
group.add_option("-d", "--debug", action="store_true",
                 help="Print debug information")
group.add_option("-s", "--sql", action="store_true",
                 help="Print all SQL statements executed")
group.add_option("-e", action="store_true", help="Print every action done")
parser.add_option_group(group)

که منجر به خروجی زیر می‌شود:

کاربرد: <yourscript> [options] arg1 arg2

گزینه‌ها:
  -h, --help            نمایش این پیام راهنما و خروج
  -v, --verbose         ایجاد سر و صدای زیاد [پیش‌فرض]
  -q, --quiet           بسیار ساکت بودن (من در حال شکار خرگوش‌ها هستم)
  -f FILE, --filename=FILE
                        نوشتن خروجی در FILE
  -m MODE, --mode=MODE  حالت تعامل: novice، intermediate یا expert
                        [پیش‌فرض: intermediate]

  گزینه‌های خطرناک:
    احتیاط: استفاده از این گزینه‌ها با مسئولیت خودتان است. اعتقاد بر این است که برخی
    از آن‌ها گاز می‌گیرند.

    -g                  گزینه گروهی.

  گزینه‌های اشکال‌زدایی:
    -d, --debug         چاپ اطلاعات اشکال‌زدایی
    -s, --sql           چاپ تمام دستورات SQL اجراشده
    -e                  چاپ هر عمل انجام‌شده

یکی دیگر از متدهای جالب، به‌ویژه هنگام کار به‌صورت برنامه‌ای با گروه‌های گزینه، عبارت است از:

OptionParser.get_option_group(opt_str)

OptionGroup ای را برگردانید که رشته‌ی گزینه‌ی کوتاه یا بلند opt_str (مثلاً '-o' یا '--option') به آن تعلق دارد. اگر چنین OptionGroup ای وجود نداشت، None را برگردانید.

چاپ رشته‌ی نسخه

همانند رشته کاربرد کوتاه، optparse همچنین می‌تواند یک رشته نسخه برای برنامه شما چاپ کند. شما باید رشته را به‌عنوان آرگومان version به OptionParser ارائه دهید:

parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")

%prog درست مانند آنچه در usage انجام می‌شود، بسط داده می‌شود. جدای از آن، version می‌تواند شامل هر چیزی باشد که شما بخواهید. هنگامی که آن را فراهم کنید، optparse به‌طور خودکار یک گزینه --version به پارسر شما اضافه می‌کند. اگر با این گزینه در خط فرمان مواجه شود، رشته version شما را (با جایگزین کردن %prog) بسط می‌دهد، آن را در stdout چاپ می‌کند و خارج می‌شود.

برای مثال، اگر اسکریپت شما /usr/bin/foo نام داشته باشد:

$ /usr/bin/foo --version
foo 1.0

می‌توان از دو متد زیر برای چاپ و دریافت رشته‌ی version استفاده کرد:

OptionParser.print_version(file=None)

پیام نسخه برنامه جاری (self.version) را در file (پیش‌فرض: stdout) چاپ می‌کند. همانند print_usage()، هر رخداد %prog در self.version با نام برنامه جاری جایگزین می‌شود. اگر self.version خالی یا تعریف‌نشده باشد، هیچ کاری انجام نمی‌دهد.

OptionParser.get_version()

مشابه print_version() است، اما به جای چاپ کردن آن، رشته نسخه را برمی‌گرداند.

چگونگی مدیریت خطاها در optparse

دو دسته‌ی کلی از خطاها وجود دارد که optparse باید به آن‌ها رسیدگی کند: خطاهای برنامه‌نویس و خطاهای کاربر. خطاهای برنامه‌نویس معمولاً فراخوانی‌های نادرست به OptionParser.add_option() هستند، مثلاً رشته‌های گزینه‌ی نامعتبر، ویژگی‌های گزینه‌ی ناشناخته، ویژگی‌های گزینه‌ی مفقود و غیره. با این موارد به شیوه‌ی معمول برخورد می‌شود: استثنایی پرتاب می‌شود (یا optparse.OptionError یا TypeError) و اجازه داده می‌شود برنامه فروپاشد.

مدیریت خطاهای کاربر بسیار مهم‌تر است، زیرا صرف‌نظر از میزان پایداری کد شما، وقوع آن‌ها حتمی است. optparse می‌تواند برخی خطاهای کاربر، مانند آرگومان‌های نامعتبر گزینه (ارسال -n 4x در جایی که -n آرگومانی از نوع عدد صحیح می‌گیرد) یا آرگومان‌های جاافتاده (-n در انتهای خط فرمان، جایی که -n آرگومانی از هر نوعی می‌گیرد) را به‌طور خودکار تشخیص دهد. همچنین می‌توانید OptionParser.error() را برای اعلام وضعیت خطای تعریف‌شده توسط برنامه فراخوانی کنید:

(options, args) = parser.parse_args()
...
if options.a and options.b:
    parser.error("options -a and -b are mutually exclusive")

در هر صورت، optparse خطا را به یک شکل مدیریت می‌کند: پیام استفاده‌ی برنامه و یک پیام خطا را در خطای استاندارد چاپ می‌کند و با وضعیت خطای ۲ خارج می‌شود.

اولین مثال بالا را در نظر بگیرید، که در آن کاربر 4x را به گزینه‌ای که یک عدد صحیح می‌پذیرد، ارسال می‌کند:

$ /usr/bin/foo -n 4x
Usage: foo [options]

foo: error: option -n: invalid integer value: '4x'

یا، در حالتی که کاربر اصلاً مقداری ارسال نمی‌کند:

$ /usr/bin/foo -n
استفاده: foo [گزینه‌ها]

foo: خطا: گزینه‌ی -n به یک آرگومان نیاز دارد

پیام‌های خطای تولیدشده توسط optparse همیشه گزینه‌ی مرتبط با خطا را ذکر می‌کنند؛ هنگام فراخوانی OptionParser.error() از کد برنامه‌تان، حتماً همین کار را انجام دهید.

اگر رفتار پیش‌فرض مدیریت خطای optparse مناسب نیازهای شما نیست، باید یک زیرکلاس از OptionParser بسازید و متدهای exit() و/یا error() آن را بازنویسی کنید.

کنار هم قرار دادن همه موارد

اسکریپت‌های مبتنی بر optparse معمولاً به این شکل هستند:

from optparse import OptionParser
...
def main():
    usage = "usage: %prog [options] arg"
    parser = OptionParser(usage)
    parser.add_option("-f", "--file", dest="filename",
                      help="read data from FILENAME")
    parser.add_option("-v", "--verbose",
                      action="store_true", dest="verbose")
    parser.add_option("-q", "--quiet",
                      action="store_false", dest="verbose")
    ...
    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error("incorrect number of arguments")
    if options.verbose:
        print("reading %s..." % options.filename)
    ...

if __name__ == "__main__":
    main()

راهنمای مرجع

ایجاد پارسر

نخستین گام در استفاده از optparse، ایجاد یک نمونه از OptionParser است.

class optparse.OptionParser(...)

سازنده‌ی OptionParser هیچ آرگومان الزامی ندارد، اما تعدادی آرگومان کلیدواژه‌ای اختیاری دارد. شما باید همیشه آن‌ها را به‌صورت آرگومان‌های کلیدواژه‌ای ارسال کنید، یعنی به ترتیب اعلام آرگومان‌ها اتکا نکنید.

usage (پیش‌فرض: "%prog [options]")

خلاصه‌ی کاربردی که هنگام اجرای نادرست برنامه‌ی شما یا همراه با گزینه‌ی راهنما چاپ می‌شود. وقتی optparse رشته‌ی کاربرد را چاپ می‌کند، %prog را به os.path.basename(sys.argv[0]) بسط می‌دهد (یا اگر آن آرگومان کلیدواژه‌ای را فرستاده باشید، به prog). برای جلوگیری از نمایش پیام کاربرد، مقدار ویژه‌ی optparse.SUPPRESS_USAGE را بفرستید.

option_list (پیش‌فرض: [])

فهرستی از اشیای Option که با آن‌ها پارسر پر می‌شود. گزینه‌های موجود در option_list پس از همه‌ی گزینه‌های موجود در standard_option_list (یک صفت کلاس که ممکن است توسط زیرکلاس‌های OptionParser تنظیم شود)، اما پیش از هر گزینه‌ی نسخه یا راهنما افزوده می‌شوند. منسوخ؛ در عوض پس از ایجاد پارسر از add_option() استفاده کنید.

option_class (پیش‌فرض: optparse.Option)

کلاس مورد استفاده هنگام افزودن گزینه‌ها به پارسر در add_option().

version (پیش‌فرض: None)

یک رشته‌ی نسخه برای چاپ هنگامی که کاربر یک گزینه‌ی نسخه ارائه می‌دهد. اگر برای version یک مقدار درست ارائه دهید، optparse به‌طور خودکار یک گزینه‌ی نسخه با تنها رشته‌ی گزینه‌ی --version اضافه می‌کند. زیررشته‌ی %prog همانند usage بسط داده می‌شود.

conflict_handler (پیش‌فرض: "error")

مشخص می‌کند که وقتی گزینه‌هایی با رشته‌های گزینه‌ی متعارض به پارسر افزوده می‌شوند، چه کاری باید انجام شود؛ بخش تعارض بین گزینه‌ها را ببینید.

description (پیش‌فرض: None)

پاراگرافی از متن که مروری کوتاه بر برنامه‌ی شما ارائه می‌دهد. optparse این پاراگراف را متناسب با عرض پایانه‌ی جاری قالب‌بندی مجدد می‌کند و هنگامی که کاربر درخواست راهنمایی می‌کند، آن را چاپ می‌کند (بعد از usage، اما قبل از فهرست گزینه‌ها).

formatter (پیش‌فرض: یک IndentedHelpFormatter جدید)

نمونه‌ای از optparse.HelpFormatter که برای چاپ متن راهنما استفاده خواهد شد. optparse دو کلاس عینی برای این منظور فراهم می‌کند: IndentedHelpFormatter و TitledHelpFormatter.

add_help_option (پیش‌فرض: True)

اگر درست باشد، optparse یک گزینه راهنما (با رشته‌های گزینه -h و --help) را به پارسر می‌افزاید.

prog

رشته‌ای که هنگام بسط %prog در usage و version به‌جای os.path.basename(sys.argv[0]) استفاده می‌شود.

epilog (پیش‌فرض: None)

بندی از متن راهنما برای نمایش پس از راهنمای گزینه.

پر کردن پارسر

چندین روش برای پر کردن پارسر با گزینه‌ها وجود دارد. روش ترجیحی استفاده از OptionParser.add_option() است، همان‌طور که در بخش آموزش نشان داده شده است. add_option() می‌تواند به یکی از دو روش فراخوانی شود:

  • یک نمونه Option (مانند آنچه make_option() برمی‌گرداند) به آن بدهید

  • هر ترکیبی از آرگومان‌های جایگاهی و کلیدواژه‌ای قابل‌قبول برای make_option() (یعنی برای سازنده‌ی Option) را به آن بدهید، تا نمونه‌ی Option را برای شما ایجاد کند

جایگزین دیگر این است که فهرستی از نمونه‌های Option از پیش ساخته‌شده را به سازنده OptionParser ارسال کنید، همان‌طور که در ادامه می‌آید:

option_list = [
    make_option("-f", "--filename",
                action="store", type="string", dest="filename"),
    make_option("-q", "--quiet",
                action="store_false", dest="verbose"),
    ]
parser = OptionParser(option_list=option_list)

(make_option() یک تابع کارخانه برای ایجاد نمونه‌های Option است؛ در حال حاضر، این تابع نام مستعاری برای سازنده‌ی Option است. نسخه‌ای آینده از optparse ممکن است Option را به چند کلاس تقسیم کند و make_option() کلاس مناسب را برای نمونه‌سازی انتخاب خواهد کرد. Option را به‌صورت مستقیم نمونه‌سازی نکنید.)

تعریف گزینه‌ها

هر نمونه از Option نشان‌دهنده مجموعه‌ای از رشته‌های گزینه خط فرمان هم‌معنی است، مثلاً -f و --file. شما می‌توانید هر تعداد رشته گزینه کوتاه یا بلند را مشخص کنید، اما باید دست‌کم یک رشته گزینه در مجموع مشخص کنید.

روش کانونیکال برای ایجاد یک نمونه از Option، استفاده از متد add_option() از OptionParser است.

OptionParser.add_option(option)
OptionParser.add_option(*opt_str, attr=value, ...)

برای تعریف گزینه‌ای فقط با یک رشته‌ی گزینه کوتاه:

parser.add_option("-f", attr=value, ...)

و برای تعریف یک گزینه فقط با یک رشته‌ی گزینه‌ی بلند:

parser.add_option("--foo", attr=value, ...)

آرگومان‌های کلیدواژه‌ای ویژگی‌های شیء جدید Option را تعریف می‌کنند. مهم‌ترین ویژگی Option action است، و تا حد زیادی تعیین می‌کند که کدام‌یک از ویژگی‌های دیگر مرتبط یا ضروری هستند. اگر ویژگی‌های Option نامرتبط را ارسال کنید یا ویژگی‌های ضروری را ارسال نکنید، optparse استثنای OptionError را پرتاب می‌کند که اشتباه شما را توضیح می‌دهد.

کنش یک گزینه مشخص می‌کند که optparse هنگام مواجهه با این گزینه در خط فرمان چه کاری انجام می‌دهد. کنش‌های استاندارد گزینه که به‌صورت سخت‌کد در optparse قرار دارند عبارتند از:

"store"

ذخیره‌ی آرگومان این گزینه (پیش‌فرض)

"store_const"

ذخیره‌ی یک مقدار ثابت، از پیش تنظیم‌شده از طریق Option.const

"store_true"

True را ذخیره می‌کند

"store_false"

False را ذخیره می‌کند

"append"

افزودن آرگومان این گزینه به یک فهرست

"append_const"

افزودن یک مقدار ثابت به یک فهرست، پیش‌تنظیم‌شده از طریق Option.const

"count"

یک شمارنده را یک واحد افزایش دهید

"callback"

فراخوانی یک تابع مشخص

"help"

یک پیام کاربرد شامل همه‌ی گزینه‌ها و مستندات آن‌ها را چاپ می‌کند

(اگر یک اکشن ارائه ندهید، پیش‌فرض "store" است. برای این کنش، همچنین می‌توانید ویژگی‌های گزینه type و dest را نیز ارائه دهید؛ اکشن‌های استاندارد گزینه‌ها را ببینید.)

همان‌طور که می‌بینید، بیشتر اکشن‌های شامل ذخیره یا به‌روزرسانی یک مقدار در جایی هستند. optparse همیشه برای این منظور یک شیء خاص ایجاد می‌کند، که به‌طور قراردادی options نامیده می‌شود و نمونه‌ای از optparse.Values است.

class optparse.Values

شیءای که نام‌های آرگومان‌های تجزیه‌شده و مقدارهای آن‌ها را به‌عنوان ویژگی‌ها نگه‌داری می‌کند. معمولاً هنگام فراخوانی OptionParser.parse_args() ایجاد می‌شود، و می‌تواند با یک زیرکلاس سفارشی که به آرگومان values در OptionParser.parse_args() ارسال می‌شود، بازنویسی شود (همان‌طور که در تجزیه‌ی آرگومان‌ها توضیح داده شده است).

آرگومان‌های گزینه (و مقادیر مختلف دیگر) به‌عنوان ویژگی‌های این شیء ذخیره می‌شوند، بر اساس ویژگی گزینه‌ی dest (مقصد).

برای مثال، هنگامی که فراخوانی می‌کنید

parser.parse_args()

یکی از اولین کارهایی که optparse انجام می‌دهد، ایجاد شیء options است:

options = Values()

اگر یکی از گزینه‌های این پارسر به این صورت تعریف شده باشد

parser.add_option("-f", "--file", action="store", type="string", dest="filename")

و خط فرمانی که تجزیه می‌شود شامل هر یک از موارد زیر است:

-ffoo
-f foo
--file=foo
--file foo

سپس optparse، با دیدن این گزینه، معادل دستور زیر را انجام می‌دهد

options.filename = "foo"

ویژگی‌های گزینه type و dest تقریباً به اندازه action مهم هستند، اما action تنها موردی است که برای همه گزینه‌ها معنا دارد.

ویژگی‌های گزینه

class optparse.Option

یک آرگومان خط فرمان واحد، با ویژگی‌های گوناگون که به‌عنوان آرگومان‌های کلیدواژه‌ای به سازنده ارسال می‌شوند. معمولاً به‌جای ایجاد مستقیم، با OptionParser.add_option() ایجاد می‌شود و می‌توان آن را با یک کلاس سفارشی از طریق آرگومان option_class برای OptionParser جایگزین کرد.

می‌توان ویژگی‌های گزینه‌ی زیر را به‌عنوان آرگومان‌های کلیدواژه‌ای به OptionParser.add_option() ارسال کرد. اگر ویژگی گزینه‌ای را ارسال کنید که به گزینه خاصی مرتبط نیست، یا ویژگی لازمِ گزینه را ارسال نکنید، optparse استثنای OptionError را پرتاب می‌کند.

Option.action

(پیش‌فرض: "store")

رفتار optparse را هنگامی که این گزینه در خط فرمان مشاهده شود، تعیین می‌کند؛ گزینه‌های موجود در اینجا مستند شده‌اند.

Option.type

(پیش‌فرض: "string")

نوع آرگومان مورد انتظار این گزینه (مثلاً "string" یا "int")؛ انواع گزینه‌های موجود در اینجا مستند شده‌اند.

Option.dest

(پیش‌فرض: مشتق‌شده از رشته‌های گزینه)

اگر کنش گزینه مستلزم نوشتن یا تغییر مقداری در جایی باشد، این به optparse می‌گوید که آن را کجا بنویسد: dest نام ویژگی‌ای از شیء options است که optparse هنگام تجزیه خط فرمان آن را می‌سازد.

Option.default

مقداری که اگر این گزینه در خط فرمان مشاهده نشود، برای مقصد این گزینه استفاده می‌شود. همچنین OptionParser.set_defaults() را ببینید.

Option.nargs

(پیش‌فرض: ۱)

هنگامی که این گزینه مشاهده می‌شود، چند آرگومان از نوع type باید مصرف شوند. اگر بیش از ۱ باشد، optparse یک تاپل از مقادیر را در dest ذخیره می‌کند.

Option.const

برای کنش‌هایی که یک مقدار ثابت را ذخیره می‌کنند، مقدار ثابتی که باید ذخیره شود.

Option.choices

برای گزینه‌هایی از نوع "choice"، فهرست رشته‌هایی که کاربر می‌تواند از میان آن‌ها انتخاب کند.

Option.callback

برای گزینه‌هایی با اکشن "callback"، شیء فراخوانی‌پذیر که هنگام مشاهده‌ی این گزینه فراخوانی می‌شود. برای جزئیات آرگومان‌های ارسال‌شده به این شیء فراخوانی‌پذیر، بخش کال‌بک‌های گزینه را ببینید.

Option.callback_args
Option.callback_kwargs

آرگومان‌های جایگاهی و کلیدواژه‌ای اضافی برای ارسال به callback پس از چهار آرگومان استاندارد کال‌بک.

Option.help

متن راهنمایی که هنگام فهرست کردن همه گزینه‌های موجود، پس از وارد کردن گزینه‌ی help توسط کاربر (مانند --help)، برای این گزینه چاپ می‌شود. اگر متن راهنمایی ارائه نشود، گزینه بدون متن راهنما فهرست خواهد شد. برای پنهان کردن این گزینه، از مقدار ویژه optparse.SUPPRESS_HELP استفاده کنید.

Option.metavar

(پیش‌فرض: مشتق‌شده از رشته‌های گزینه)

جایگزینی برای آرگومان(های) گزینه جهت استفاده هنگام چاپ متن راهنما. برای دیدن یک مثال، بخش آموزش را ببینید.

اکشن‌های استاندارد گزینه‌ها

کنش‌های مختلف گزینه همگی الزامات و اثرات کمی متفاوتی دارند. بیشتر کنش‌ها چندین ویژگی مرتبط با گزینه دارند که می‌توانید آن‌ها را برای هدایت رفتار optparse مشخص کنید؛ تعداد کمی دارای ویژگی‌های الزامی هستند که باید آن‌ها را برای هر گزینه‌ای که از آن کنش استفاده می‌کند مشخص کنید.

  • "store" [مرتبط: type، dest، nargs، choices]

    پس از این گزینه باید یک آرگومان بیاید که بر اساس type به یک مقدار تبدیل می‌شود و در dest ذخیره می‌شود. اگر nargs > 1 باشد، چند آرگومان از خط فرمان مصرف می‌شوند؛ تمام آن‌ها بر اساس type تبدیل می‌شوند و به‌صورت یک تاپل در dest ذخیره می‌شوند. بخش انواع گزینه‌های استاندارد را ببینید.

    اگر choices ارائه شده باشد (یک فهرست یا تاپل از رشته‌ها)، نوع به‌طور پیش‌فرض "choice" خواهد بود.

    اگر type ارائه نشود، مقدار پیش‌فرض آن "string" خواهد بود.

    اگر dest ارائه نشود، optparse مقصدی را از اولین رشته‌ی گزینه‌ی بلند استخراج می‌کند (برای مثال، --foo-bar به معنای foo_bar است). اگر هیچ رشته‌ی گزینه‌ی بلندی وجود نداشته باشد، optparse مقصدی را از اولین رشته‌ی گزینه‌ی کوتاه استخراج می‌کند (برای مثال، -f به معنای f است).

    مثال:

    parser.add_option("-f")
    parser.add_option("-p", type="float", nargs=3, dest="point")
    

    هنگام تجزیه خط فرمان

    -f foo.txt -p 1 -3.5 4 -fbar.txt
    

    optparse تنظیم خواهد کرد

    options.f = "foo.txt"
    options.point = (1.0, -3.5, 4.0)
    options.f = "bar.txt"
    
  • "store_const" [الزامی: const؛ مرتبط: dest]

    مقدار const در dest ذخیره می‌شود.

    مثال:

    parser.add_option("-q", "--quiet",
                      action="store_const", const=0, dest="verbose")
    parser.add_option("-v", "--verbose",
                      action="store_const", const=1, dest="verbose")
    parser.add_option("--noisy",
                      action="store_const", const=2, dest="verbose")
    

    اگر --noisy دیده شود، optparse تنظیم خواهد کرد

    options.verbose = 2
    
  • "store_true" [مرتبط: dest]

    حالت خاصی از "store_const" که True را در dest ذخیره می‌کند.

  • "store_false" [مرتبط: dest]

    مانند "store_true"، اما False را ذخیره می‌کند.

    مثال:

    parser.add_option("--clobber", action="store_true", dest="clobber")
    parser.add_option("--no-clobber", action="store_false", dest="clobber")
    
  • "append" [مرتبط: type، dest، nargs، choices]

    پس از این گزینه باید یک آرگومان بیاید، که به فهرست موجود در dest افزوده می‌شود. اگر مقدار پیش‌فرضی برای dest ارائه نشده باشد، هنگامی که optparse برای اولین بار این گزینه را در خط فرمان مشاهده کند، به‌طور خودکار یک فهرست خالی ایجاد می‌شود. اگر nargs > ۱ باشد، چندین آرگومان مصرف می‌شود و تاپلی به طول nargs به dest افزوده می‌شود.

    مقادیر پیش‌فرض برای type و dest همان مقادیر پیش‌فرض برای کنش "store" هستند.

    مثال:

    parser.add_option("-t", "--tracks", action="append", type="int")
    

    اگر -t3 در خط فرمان دیده شود، optparse معادل زیر را انجام می‌دهد:

    options.tracks = []
    options.tracks.append(int("3"))
    

    اگر کمی بعد --tracks=4 دیده شود، این کار را انجام می‌دهد:

    options.tracks.append(int("4"))
    

    اکشن append، متد append را روی مقدار فعلی گزینه فراخوانی می‌کند. این بدان معناست که هر مقدار پیش‌فرض مشخص‌شده باید یک متد append داشته باشد. همچنین بدان معناست که اگر مقدار پیش‌فرض غیرخالی باشد، عناصر پیش‌فرض در مقدار تجزیه‌شده برای گزینه وجود خواهند داشت و هر مقداری از خط فرمان پس از آن مقادیر پیش‌فرض اضافه می‌شود:

    >>> parser.add_option("--files", action="append", default=['~/.mypkg/defaults'])
    >>> opts, args = parser.parse_args(['--files', 'overrides.mypkg'])
    >>> opts.files
    ['~/.mypkg/defaults', 'overrides.mypkg']
    
  • "append_const" [الزامی: const؛ مرتبط: dest]

    مانند "store_const"، اما مقدار const به dest افزوده می‌شود؛ همانند "append"، مقدار پیش‌فرض dest برابر None است و در اولین مواجهه با گزینه، یک فهرست خالی به‌طور خودکار ایجاد می‌شود.

  • "count" [مرتبط: dest]

    عدد صحیح ذخیره‌شده در dest را افزایش می‌دهد. اگر مقدار پیش‌فرضی ارائه نشود، dest پیش از نخستین افزایش، روی صفر تنظیم می‌شود.

    مثال:

    parser.add_option("-v", action="count", dest="verbosity")
    

    نخستین باری که -v در خط فرمان دیده شود، optparse معادل زیر را انجام می‌دهد:

    options.verbosity = 0
    options.verbosity += 1
    

    هر تکرار بعدی -v منجر می‌شود به

    options.verbosity += 1
    
  • "callback" [الزامی: callback؛ مرتبط: type، nargs، callback_args، callback_kwargs]

    تابع مشخص‌شده توسط callback را فراخوانی می‌کند، که به‌صورت زیر فراخوانی می‌شود

    func(option, opt_str, value, parser, *args, **kwargs)
    

    برای جزئیات بیشتر، بخش کال‌بک‌های گزینه را ببینید.

  • "help"

    یک پیام راهنمای کامل برای همه‌ی گزینه‌ها در پارسر فعلی گزینه‌ها (option parser) چاپ می‌کند. پیام راهنما از رشته‌ی usage ارسال‌شده به سازنده‌ی OptionParser و رشته‌ی help ارسال‌شده به هر گزینه ساخته می‌شود.

    اگر برای یک گزینه، رشته‌ی help ارائه نشود، آن گزینه همچنان در پیام راهنما فهرست می‌شود. برای حذف کامل یک گزینه، از مقدار ویژه‌ی optparse.SUPPRESS_HELP استفاده کنید.

    optparse به‌طور خودکار گزینه‌ی help را به تمام OptionParserها اضافه می‌کند، بنابراین شما معمولاً نیازی به ایجاد آن ندارید.

    مثال:

    from optparse import OptionParser, SUPPRESS_HELP
    
    # usually, a help option is added automatically, but that can
    # be suppressed using the add_help_option argument
    parser = OptionParser(add_help_option=False)
    
    parser.add_option("-h", "--help", action="help")
    parser.add_option("-v", action="store_true", dest="verbose",
                      help="Be moderately verbose")
    parser.add_option("--file", dest="filename",
                      help="Input file to read data from")
    parser.add_option("--secret", help=SUPPRESS_HELP)
    

    اگر optparse هر یک از -h یا --help را در خط فرمان ببیند، چیزی شبیه پیام راهنمای زیر را در stdout چاپ می‌کند (با فرض اینکه sys.argv[0] برابر "foo.py" باشد):

    طرز استفاده: foo.py [گزینه‌ها]
    
    گزینه‌ها:
      -h, --help        نمایش این پیام راهنما و خروج
      -v                تا حدی پرگو باشد
      --file=FILENAME   پرونده ورودی برای خواندن داده‌ها از آن
    

    پس از چاپ پیام راهنما، optparse فرایند شما را با sys.exit(0) خاتمه می‌دهد.

  • "version"

    شماره نسخه ارائه‌شده به OptionParser را در stdout چاپ می‌کند و خارج می‌شود. شماره نسخه در واقع توسط متد print_version() از OptionParser قالب‌بندی و چاپ می‌شود. به‌طور کلی فقط در صورتی مرتبط است که آرگومان version به سازنده OptionParser ارائه شده باشد. مانند گزینه‌های help، به‌ندرت گزینه‌های version را ایجاد خواهید کرد، زیرا optparse در صورت نیاز آن‌ها را به‌طور خودکار اضافه می‌کند.

انواع گزینه‌های استاندارد

optparse دارای پنج نوع گزینه‌ی توکار است: "string"، "int"، "choice"، "float" و "complex". اگر نیاز به افزودن انواع جدید گزینه دارید، بخش گسترش optparse را ببینید.

آرگومان‌های مربوط به گزینه‌های رشته‌ای به هیچ وجه بررسی یا تبدیل نمی‌شوند: متن خط فرمان، همان‌طور که هست، در مقصد ذخیره می‌شود (یا به کال‌بک ارسال می‌شود).

آرگومان‌های عدد صحیح (نوع "int") به‌صورت زیر تجزیه می‌شوند:

  • اگر عدد با 0x شروع شود، به‌عنوان عدد مبنای شانزده تجزیه می‌شود

  • اگر عدد با 0 شروع شود، به‌عنوان عدد مبنای هشت تجزیه می‌شود

  • اگر عدد با 0b شروع شود، به‌عنوان یک عدد مبنای دو تجزیه می‌شود

  • در غیر این صورت، عدد به‌عنوان یک عدد مبنای ده تجزیه می‌شود

این تبدیل با فراخوانی int() با مبنای مناسب (۲، ۸، ۱۰ یا ۱۶) انجام می‌شود. اگر این تبدیل ناموفق باشد، optparse نیز ناموفق خواهد بود، هرچند با پیام خطای مفیدتری.

آرگومان‌های گزینه "float" و "complex" مستقیماً با float() و complex() تبدیل می‌شوند و مدیریت خطای مشابهی دارند.

گزینه‌های "choice" زیرنوعی از گزینه‌های "string" هستند. ویژگی گزینه choices (یک دنباله از رشته‌ها) مجموعه‌ای از آرگومان‌های مجاز گزینه را تعریف می‌کند. optparse.check_choice() آرگومان‌های گزینه ارائه‌شده توسط کاربر را با این فهرست مرجع مقایسه می‌کند و اگر رشته نامعتبری داده شود، OptionValueError را پرتاب می‌کند.

تجزیه‌ی آرگومان‌ها

هدف اصلی از ایجاد و پر کردن یک OptionParser، فراخوانی متد parse_args() آن است.

OptionParser.parse_args(args=None, values=None)

گزینه‌های خط فرمان موجود در args را تجزیه کنید.

پارامترهای ورودی عبارتند از

args

فهرست آرگومان‌ها برای پردازش (پیش‌فرض: sys.argv[1:])

values

یک شیء Values برای ذخیره‌ی آرگومان‌های گزینه در آن (پیش‌فرض: یک نمونه جدید از Values) -- اگر یک شیء موجود بدهید، پیش‌فرض‌های گزینه‌ها روی آن مقداردهی اولیه نمی‌شوند

و مقدار بازگشتی یک جفت (options, args) است که

options

همان شیءای که به‌عنوان values ارسال شده است، یا نمونه‌ی optparse.Values که توسط optparse ایجاد شده است

args

آرگومان‌های جایگاهی باقی‌مانده پس از پردازش همه‌ی گزینه‌ها

رایج‌ترین کاربرد این است که هیچ‌یک از آرگومان‌های کلیدواژه‌ای ارائه نشود. اگر values را ارائه دهید، با فراخوانی‌های مکرر setattr() تغییر داده می‌شود (تقریباً یک فراخوانی برای هر آرگومان گزینه‌ای که در یک مقصد گزینه ذخیره می‌شود) و توسط parse_args() برگردانده می‌شود.

اگر parse_args() با خطایی در فهرست آرگومان‌ها مواجه شود، متد error() از OptionParser را با یک پیام خطای مناسب برای کاربر نهایی فراخوانی می‌کند. این موضوع در نهایت فرایند شما را با وضعیت خروجی ۲ (وضعیت خروجی مرسوم یونیکس برای خطاهای خط فرمان) خاتمه می‌دهد.

پرس‌وجو و دستکاری پارسر گزینه‌های شما (option parser)

رفتار پیش‌فرض پارسر گزینه‌ها (option parser) را می‌توان تا حدی سفارشی کرد، و شما همچنین می‌توانید در پارسر گزینه‌های خود کاوش کنید و ببینید چه مواردی در آن وجود دارد. OptionParser چندین متد برای کمک به شما فراهم می‌کند:

OptionParser.disable_interspersed_args()

تجزیه را طوری تنظیم کنید که در اولین آرگومانی که گزینه نیست متوقف شود. برای مثال، اگر -a و -b هر دو گزینه‌های ساده‌ای باشند که آرگومانی نمی‌گیرند، optparse معمولاً این سینتکس را می‌پذیرد:

prog -a arg1 -b arg2

و آن را معادل در نظر می‌گیرد

prog -a -b arg1 arg2

برای غیرفعال کردن این قابلیت، disable_interspersed_args() را فراخوانی کنید. این کار سینتکس سنتی یونیکس را بازمی‌گرداند، که در آن تجزیه گزینه‌ها با نخستین آرگومان غیرگزینه‌ای متوقف می‌شود.

اگر پردازنده‌ی فرمانی دارید که فرمان دیگری با گزینه‌های خودش را اجرا می‌کند و می‌خواهید مطمئن شوید که این گزینه‌ها اشتباه گرفته نمی‌شوند، از این استفاده کنید. برای مثال، ممکن است هر فرمان مجموعه‌ای متفاوت از گزینه‌ها داشته باشد.

OptionParser.enable_interspersed_args()

تجزیه را طوری تنظیم کنید که در نخستین غیرگزینه متوقف نشود و امکان قرار دادن سوئیچ‌ها در میان آرگومان‌های فرمان فراهم شود. این رفتار پیش‌فرض است.

OptionParser.get_option(opt_str)

نمونه‌ی Option با رشته‌ی گزینه opt_str را برمی‌گرداند، یا اگر هیچ گزینه‌ای آن رشته‌ی گزینه را نداشته باشد، None را برمی‌گرداند.

OptionParser.has_option(opt_str)

اگر OptionParser گزینه‌ای با رشته‌ی گزینه opt_str (مثلاً -q یا --verbose) داشته باشد، True را برمی‌گرداند.

OptionParser.remove_option(opt_str)

اگر OptionParser گزینه‌ای متناظر با opt_str داشته باشد، آن گزینه حذف می‌شود. اگر آن گزینه رشته‌های گزینه‌ی دیگری را فراهم کرده باشد، همه‌ی آن رشته‌های گزینه نامعتبر می‌شوند. اگر opt_str در هیچ‌یک از گزینه‌های متعلق به این OptionParser وجود نداشته باشد، ValueError پرتاب می‌شود.

تعارض بین گزینه‌ها

اگر مراقب نباشید، به‌راحتی می‌توانید گزینه‌هایی با رشته‌های گزینه متعارض تعریف کنید:

parser.add_option("-n", "--dry-run", ...)
...
parser.add_option("-n", "--noisy", ...)

(این امر به‌ویژه زمانی صادق است که شما زیرکلاس OptionParser خودتان را با برخی گزینه‌های استاندارد تعریف کرده باشید.)

هر بار که گزینه‌ای را اضافه می‌کنید، optparse تعارض‌های آن با گزینه‌های موجود را بررسی می‌کند. اگر موردی پیدا کند، سازوکار فعلی مدیریت تعارض را فراخوانی می‌کند. می‌توانید سازوکار مدیریت تعارض را یا در سازنده تنظیم کنید:

parser = OptionParser(..., conflict_handler=handler)

یا با یک فراخوانی جداگانه:

parser.set_conflict_handler(handler)

مدیرهای تعارض (conflict handlers) موجود عبارتند از:

"error" (پیش‌فرض)

تداخل گزینه‌ها را یک خطای برنامه‌نویسی فرض می‌کند و OptionConflictError را پرتاب می‌کند

"resolve"

حل تعارض گزینه‌ها به‌صورت هوشمندانه (در زیر ببینید)

به‌عنوان مثال، بیایید یک OptionParser تعریف کنیم که تعارض‌ها را به‌صورت هوشمندانه حل کند و گزینه‌های متعارض را به آن اضافه کنیم:

parser = OptionParser(conflict_handler="resolve")
parser.add_option("-n", "--dry-run", ..., help="do no harm")
parser.add_option("-n", "--noisy", ..., help="be noisy")

در این نقطه، optparse تشخیص می‌دهد که گزینه‌ای که پیش‌تر افزوده شده است، در حال حاضر از رشته‌ی گزینه‌ی -n استفاده می‌کند. از آن‌جا که conflict_handler برابر "resolve" است، این موقعیت را با حذف -n از فهرست رشته‌های گزینه‌ی مربوط به گزینه‌ی پیشین حل می‌کند. اکنون --dry-run تنها راه کاربر برای فعال‌سازی آن گزینه است. اگر کاربر راهنمایی بخواهد، پیام راهنمایی این موضوع را منعکس خواهد کرد:

Options:
  --dry-run     do no harm
  ...
  -n, --noisy   be noisy

می‌توان رشته‌های گزینه‌ی یک گزینه‌ی پیش‌تر افزوده‌شده را به‌تدریج حذف کرد تا هیچ رشته‌ای باقی نماند و کاربر دیگر راهی برای فراخوانی آن گزینه از خط فرمان نداشته باشد. در این صورت، optparse آن گزینه را به‌طور کامل حذف می‌کند، بنابراین در متن راهنما یا هیچ جای دیگری نمایش داده نمی‌شود. ادامه‌ی کار با OptionParser موجود:

parser.add_option("--dry-run", ..., help="new dry-run option")

در این نقطه، گزینه اصلی -n/--dry-run دیگر در دسترس نیست، بنابراین optparse آن را حذف می‌کند و این متن راهنما را باقی می‌گذارد:

Options:
  ...
  -n, --noisy   be noisy
  --dry-run     new dry-run option

پاک‌سازی

نمونه‌های OptionParser چندین ارجاع حلقه‌ای دارند. این موضوع نباید برای زباله‌رو پایتون مشکلی ایجاد کند، اما ممکن است بخواهید پس از اتمام کار با OptionParser خود، با فراخوانی destroy() روی آن، ارجاع‌های حلقه‌ای را به‌صراحت بشکنید. این کار به‌ویژه در برنامه‌های با اجرای طولانی مفید است که در آن‌ها گراف‌های بزرگ شیء از OptionParser شما قابل‌دسترسی هستند.

متدهای دیگر

OptionParser از چندین متد عمومی دیگر پشتیبانی می‌کند:

OptionParser.set_usage(usage)

رشته کاربرد را مطابق قواعدی که در بالا برای آرگومان کلیدواژه‌ای usage در سازنده توضیح داده شد، تنظیم کنید. با گذراندن None، رشته کاربرد پیش‌فرض تنظیم می‌شود؛ برای جلوگیری از نمایش پیام کاربرد از optparse.SUPPRESS_USAGE استفاده کنید.

OptionParser.print_usage(file=None)

پیام طرز استفاده برای برنامه جاری (self.usage) را در file (پیش‌فرض stdout) چاپ می‌کند. هر مورد از رشته %prog در self.usage با نام برنامه جاری جایگزین می‌شود. اگر self.usage خالی یا تعریف‌نشده باشد، کاری انجام نمی‌دهد.

OptionParser.get_usage()

مانند print_usage() است اما به جای چاپ کردن، رشته‌ی کاربرد را برمی‌گرداند.

OptionParser.set_defaults(dest=value, ...)

مقادیر پیش‌فرض چندین مقصد گزینه را یک‌جا تنظیم کنید. استفاده از set_defaults() روش ترجیح‌داده‌شده برای تنظیم مقادیر پیش‌فرض گزینه‌ها است، زیرا چندین گزینه می‌توانند یک مقصد مشترک داشته باشند. برای مثال، اگر چندین گزینه‌ی «mode» همگی یک مقصد را تنظیم کنند، هر یک از آن‌ها می‌تواند مقدار پیش‌فرض را تنظیم کند و آخرین گزینه برنده است:

parser.add_option("--advanced", action="store_const",
                  dest="mode", const="advanced",
                  default="novice")    # overridden below
parser.add_option("--novice", action="store_const",
                  dest="mode", const="novice",
                  default="advanced")  # overrides above setting

برای اجتناب از این سردرگمی، از set_defaults() استفاده کنید:

parser.set_defaults(mode="advanced")
parser.add_option("--advanced", action="store_const",
                  dest="mode", const="advanced")
parser.add_option("--novice", action="store_const",
                  dest="mode", const="novice")

کال‌بک‌های گزینه

هنگامی که کنش‌ها و انواع توکار optparse برای نیازهای شما کاملاً کافی نیستند، دو انتخاب دارید: گسترش optparse یا تعریف یک گزینه‌ی کال‌بک. گسترش optparse عمومی‌تر است، اما برای بسیاری از موارد ساده زیاده‌روی است. اغلب یک کال‌بک ساده تمام چیزی است که نیاز دارید.

تعریف یک گزینه‌ی کال‌بک دو مرحله دارد:

  • خود گزینه را با استفاده از کنش "callback" تعریف کنید

  • کال‌بک را بنویسید؛ این یک تابع (یا متد) است که حداقل ۴ آرگومان دریافت می‌کند، همان‌طور که در زیر توضیح داده شده است

تعریف یک گزینه‌ی کال‌بک

مانند همیشه، ساده‌ترین راه برای تعریف یک گزینه‌ی کال‌بک، استفاده از متد OptionParser.add_option() است. به جز action، تنها ویژگی گزینه‌ای که باید مشخص کنید callback است، یعنی تابعی که باید فراخوانی شود:

parser.add_option("-c", action="callback", callback=my_callback)

callback یک تابع (یا شیء فراخوانی‌پذیر دیگر) است، بنابراین هنگام ایجاد این گزینه‌ی کال‌بک، باید از قبل my_callback() را تعریف کرده باشید. در این حالت ساده، optparse حتی نمی‌داند که -c آرگومانی می‌گیرد یا خیر، که معمولاً به این معناست که این گزینه آرگومانی ندارد—صرف وجود -c در خط فرمان تنها چیزی است که باید بداند. هرچند در برخی شرایط، ممکن است بخواهید کال‌بک شما تعداد دلخواهی از آرگومان‌های خط فرمان را مصرف کند. اینجاست که نوشتن کال‌بک‌ها دشوار می‌شود؛ این موضوع بعداً در همین بخش پوشش داده می‌شود.

optparse همیشه چهار آرگومان مشخص را به کال‌بک شما ارسال می‌کند، و تنها در صورتی آرگومان‌های اضافی را ارسال می‌کند که آن‌ها را از طریق callback_args و callback_kwargs مشخص کرده باشید. بنابراین، حداقل امضای تابع کال‌بک به این صورت است:

def my_callback(option, opt, value, parser):

چهار آرگومان یک کال‌بک در زیر توضیح داده شده‌اند.

چند ویژگی دیگر برای گزینه وجود دارد که می‌توانید هنگام تعریف یک گزینه کال‌بک آن‌ها را ارائه کنید:

type

معنای معمول خود را دارد: مانند کنش‌های "store" یا "append"، به optparse دستور می‌دهد یک آرگومان را مصرف کند و آن را به type تبدیل کند. البته به‌جای ذخیره کردن مقدار(های) تبدیل‌شده در جایی، optparse آن را به تابع کال‌بک شما ارسال می‌کند.

nargs

همچنین معنای معمول خود را دارد: اگر ارائه شود و بزرگ‌تر از ۱ باشد، optparse nargs آرگومان را مصرف می‌کند، که هر یک باید بتواند به type تبدیل شود. سپس یک تاپل از مقادیر تبدیل‌شده را به کال‌بک شما می‌دهد.

callback_args

یک تاپل از آرگومان‌های جایگاهی اضافی برای ارسال به کال‌بک

callback_kwargs

یک دیکشنری از آرگومان‌های کلیدواژه‌ای اضافی برای فرستادن به کال‌بک

نحوه فراخوانی کال‌بک‌ها

تمام کال‌بک‌ها به‌صورت زیر فراخوانی می‌شوند:

func(option, opt_str, value, parser, *args, **kwargs)

که در آن

option

نمونه‌ی Option است که کال‌بک را فراخوانی می‌کند

opt_str

رشته‌ی گزینه‌ی مشاهده‌شده در خط فرمان است که باعث فراخوانی کال‌بک می‌شود. (اگر از یک گزینه‌ی بلند مخفف‌شده استفاده شده باشد، opt_str رشته‌ی گزینه‌ی کامل و کانونیکال خواهد بود---مثلاً اگر کاربر --foo را به‌عنوان مخفف --foobar در خط فرمان وارد کند، آنگاه opt_str برابر "--foobar" خواهد بود.)

value

آرگومان این گزینه است که در خط فرمان دیده می‌شود. optparse تنها در صورتی منتظر آرگومان است که type تنظیم شده باشد؛ نوع value همان نوعی خواهد بود که از نوع گزینه برداشت می‌شود. اگر type برای این گزینه None باشد (آرگومانی انتظار نمی‌رود)، آنگاه value برابر None خواهد بود. اگر nargs > 1 باشد، value تاپلی از مقادیر با نوع مناسب خواهد بود.

parser

نمونه‌ی OptionParser است که کل فرآیند را هدایت می‌کند و عمدتاً مفید است، زیرا می‌توانید از طریق ویژگی‌های نمونه‌ی آن به برخی داده‌های جالب دیگر دسترسی داشته باشید:

parser.largs

فهرست کنونی آرگومان‌های باقی‌مانده، یعنی آرگومان‌هایی که مصرف شده‌اند اما نه گزینه‌ها و نه آرگومان‌های گزینه هستند. می‌توانید parser.largs را تغییر دهید، برای مثال با افزودن آرگومان‌های بیشتر به آن. (این فهرست به args تبدیل خواهد شد، دومین مقدار بازگشتی parse_args().)

parser.rargs

فهرست جاری آرگومان‌های باقی‌مانده، یعنی فهرستی که opt_str و value (در صورت اقتضا) از آن حذف شده‌اند و تنها آرگومان‌های پس از آن‌ها هنوز موجودند. می‌توانید parser.rargs را تغییر دهید، برای مثال با مصرف آرگومان‌های بیشتر.

parser.values

شیءای که مقادیر گزینه‌ها به‌طور پیش‌فرض در آن ذخیره می‌شوند (نمونه‌ای از optparse.OptionValues). این به کال‌بک‌ها اجازه می‌دهد که برای ذخیره‌ی مقادیر گزینه‌ها از همان مکانیزم بقیه‌ی optparse استفاده کنند؛ شما نیازی نیست با متغیرهای سراسری (globals) یا بسته‌ها (closures) سروکار داشته باشید. همچنین می‌توانید به مقدار(های) هر یک از گزینه‌هایی که پیش‌تر در خط فرمان با آن‌ها مواجه شده‌اید، دسترسی پیدا کنید یا آن‌ها را تغییر دهید.

args

یک تاپل از آرگومان‌های جایگاهی دلخواه است که از طریق ویژگی گزینه‌ی callback_args تأمین می‌شود.

kwargs

دیکشنری‌ای از آرگومان‌های کلیدواژه‌ای دلخواه است که از طریق callback_kwargs ارائه شده است.

پرتاب خطاها در کال‌بک

تابع کال‌بک باید در صورت وجود هرگونه مشکل در گزینه یا آرگومان‌های آن، OptionValueError را پرتاب کند. optparse آن را می‌گیرد و برنامه را خاتمه می‌دهد و پیام خطایی را که شما ارائه می‌کنید در stderr چاپ می‌کند. پیام شما باید روشن، مختصر و دقیق باشد و گزینه‌ی دارای خطا را ذکر کند. در غیر این صورت، کاربر برای فهمیدن این‌که چه اشتباهی کرده است دچار مشکل خواهد شد.

مثال کال‌بک ۱: کال‌بک ساده

در اینجا مثالی از یک گزینه‌ی کال‌بک آمده است که هیچ آرگومانی نمی‌گیرد و به‌سادگی دیده‌شدن گزینه را ثبت می‌کند:

def record_foo_seen(option, opt_str, value, parser):
    parser.values.saw_foo = True

parser.add_option("--foo", action="callback", callback=record_foo_seen)

البته، می‌توانید این کار را با کنش "store_true" انجام دهید.

مثال کال‌بک ۲: بررسی ترتیب گزینه‌ها

در اینجا مثالی کمی جالب‌تر آمده است: این واقعیت را ثبت می‌کند که -a دیده شده است، اما اگر در خط فرمان بعد از -b بیاید، با خطا مواجه می‌شود.

def check_order(option, opt_str, value, parser):
    if parser.values.b:
        raise OptionValueError("can't use -a after -b")
    parser.values.a = 1
...
parser.add_option("-a", action="callback", callback=check_order)
parser.add_option("-b", action="store_true", dest="b")

مثال کال‌بک ۳: بررسی ترتیب گزینه‌ها (تعمیم‌یافته)

اگر می‌خواهید از این کال‌بک برای چند گزینه مشابه مجدداً استفاده کنید (پرچمی را تنظیم کند، اما اگر -b قبلاً دیده شده باشد با خطا مواجه شود)، به کمی کار نیاز دارد: پیام خطا و پرچمی که تنظیم می‌کند باید تعمیم داده شوند.

def check_order(option, opt_str, value, parser):
    if parser.values.b:
        raise OptionValueError("can't use %s after -b" % opt_str)
    setattr(parser.values, option.dest, 1)
...
parser.add_option("-a", action="callback", callback=check_order, dest='a')
parser.add_option("-b", action="store_true", dest="b")
parser.add_option("-c", action="callback", callback=check_order, dest='c')

مثال کال‌بک ۴: بررسی شرط دلخواه

البته، می‌توانید هر شرطی را در آن قرار دهید—شما به بررسی مقادیر گزینه‌های از پیش تعریف‌شده محدود نیستید. برای مثال، اگر گزینه‌هایی دارید که نباید هنگامی که ماه کامل است فراخوانی شوند، تنها کاری که باید انجام دهید این است:

def check_moon(option, opt_str, value, parser):
    if is_moon_full():
        raise OptionValueError("%s option invalid when moon is full"
                               % opt_str)
    setattr(parser.values, option.dest, 1)
...
parser.add_option("--foo",
                  action="callback", callback=check_moon, dest="foo")

(تعریف is_moon_full() به‌عنوان تمرینی برای خواننده باقی مانده است.)

مثال ۵ کال‌بک: آرگومان‌های ثابت

هنگامی که گزینه‌های کال‌بکی تعریف می‌کنید که تعداد ثابتی آرگومان می‌گیرند، همه‌چیز کمی جالب‌تر می‌شود. مشخص کردن اینکه یک گزینه کال‌بکی آرگومان می‌گیرد، مشابه تعریف یک گزینه "store" یا "append" است: اگر type را تعریف کنید، گزینه یک آرگومان می‌گیرد که باید بتواند به آن نوع تبدیل شود؛ اگر nargs را نیز تعریف کنید، گزینه nargs آرگومان می‌گیرد.

در اینجا مثالی آمده است که فقط کنش استاندارد "store" را شبیه‌سازی می‌کند:

def store_value(option, opt_str, value, parser):
    setattr(parser.values, option.dest, value)
...
parser.add_option("--foo",
                  action="callback", callback=store_value,
                  type="int", nargs=3, dest="foo")

توجه داشته باشید که optparse مصرف ۳ آرگومان و تبدیل آن‌ها به اعداد صحیح را برای شما بر عهده می‌گیرد؛ تنها کاری که باید انجام دهید، ذخیره کردن آن‌ها است. (یا هر چیز دیگر؛ بدیهی است که برای این مثال به کال‌بک نیازی ندارید.)

مثال کال‌بک ۶: آرگومان‌های متغیر

هنگامی که بخواهید یک گزینه تعداد متغیری آرگومان بپذیرد، کار پیچیده می‌شود. در این حالت، باید یک کال‌بک بنویسید، زیرا optparse هیچ قابلیت توکاری برای آن فراهم نمی‌کند. و باید با برخی پیچیدگی‌های تجزیه‌ی مرسوم خط فرمان در یونیکس سروکار داشته باشید که optparse معمولاً آن‌ها را برای شما مدیریت می‌کند. به‌طور خاص، کال‌بک‌ها باید قواعد مرسوم برای آرگومان‌های خالی -- و - را پیاده‌سازی کنند:

  • هر یک از -- یا - می‌توانند آرگومان‌های گزینه باشند

  • -- به‌تنهایی (اگر آرگومان یک گزینه نباشد): پردازش خط فرمان را متوقف می‌کند و -- را نادیده می‌گیرد

  • - خالی (اگر آرگومان یک گزینه نباشد): پردازش خط فرمان را متوقف می‌کند، اما - را نگه می‌دارد (آن را به parser.largs اضافه می‌کند)

اگر گزینه‌ای می‌خواهید که تعداد متغیری از آرگومان‌ها را می‌پذیرد، چند مسئله ظریف و دشوار وجود دارد که باید به آن‌ها توجه کنید. پیاده‌سازی دقیقی که انتخاب می‌کنید بر اساس مصالحه‌هایی خواهد بود که حاضرید برای برنامه خود بپذیرید (به همین دلیل optparse به‌طور مستقیم از این نوع موارد پشتیبانی نمی‌کند).

با این حال، در اینجا تلاشی برای پیاده‌سازی یک کال‌بک برای گزینه‌ای با آرگومان‌های متغیر ارائه شده است:

def vararg_callback(option, opt_str, value, parser):
    assert value is None
    value = []

    def floatable(str):
        try:
            float(str)
            return True
        except ValueError:
            return False

    for arg in parser.rargs:
        # stop on --foo like options
        if arg[:2] == "--" and len(arg) > 2:
            break
        # stop on -a, but not on -3 or -3.0
        if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
            break
        value.append(arg)

    del parser.rargs[:len(value)]
    setattr(parser.values, option.dest, value)

...
parser.add_option("-c", "--callback", dest="vararg_attr",
                  action="callback", callback=vararg_callback)

گسترش optparse

از آن‌جا که دو عامل اصلی کنترل‌کننده چگونگی تفسیر گزینه‌های خط فرمان توسط optparse، اکشن و نوع هر گزینه هستند، محتمل‌ترین مسیر توسعه، افزودن کنش‌های جدید و انواع جدید است.

افزودن نوع‌های جدید

برای افزودن نوع‌های جدید، باید زیرکلاس خودتان از کلاس Option در optparse را تعریف کنید. این کلاس دارای چند ویژگی است که نوع‌های optparse را تعریف می‌کنند: TYPES و TYPE_CHECKER.

Option.TYPES

یک تاپلاز نام‌های نوع؛ در زیرکلاس خود، به‌سادگی یک تاپل جدید به نام TYPES تعریف کنید که بر پایه‌ی تاپل استاندارد ساخته می‌شود.

Option.TYPE_CHECKER

یک دیکشنری که نام انواع را به توابع بررسی نوع نگاشت می‌کند. یک تابع بررسی نوع دارای امضای زیر است:

def check_mytype(option, opt, value)

که در آن option یک نمونه از Option، opt یک رشته‌ی گزینه (برای مثال -f) و value رشته‌ای از خط فرمان است که باید بررسی و به نوع دلخواه شما تبدیل شود. check_mytype() باید شیءای از نوع فرضی mytype را برگرداند. مقداری که یک تابع بررسی نوع بازمی‌گرداند، در نهایت در نمونه‌ی OptionValues بازگشتی از OptionParser.parse_args() قرار خواهد گرفت، یا به‌عنوان پارامتر value به یک کال‌بک ارسال می‌شود.

تابع بررسی نوع شما باید در صورت مواجهه با هرگونه مشکل، OptionValueError را پرتاب کند. OptionValueError تنها یک آرگومان رشته‌ای دریافت می‌کند که به‌همان‌صورت به متد error() از OptionParser منتقل می‌شود؛ این متد به‌نوبه خود نام برنامه و رشته "error:" را به ابتدای آن اضافه می‌کند و همه‌چیز را پیش از خاتمه فرایند در stderr چاپ می‌کند.

در اینجا مثالی پیش‌پاافتاده آورده شده است که اضافه کردن نوع گزینه‌ی "complex" برای تجزیه‌ی اعداد مختلط به‌سبک پایتون در خط فرمان را نشان می‌دهد. (این مثال حتی از قبل پیش‌پاافتاده‌تر است، زیرا optparse 1.3 پشتیبانی توکار از اعداد مختلط را اضافه کرده است، اما مهم نیست.)

ابتدا، ایمپورت‌های لازم:

from copy import copy
from optparse import Option, OptionValueError

شما باید ابتدا بررسی‌کننده نوع خود را تعریف کنید، زیرا بعداً به آن ارجاع داده می‌شود (در ویژگی کلاس TYPE_CHECKER از زیرکلاس Option شما):

def check_complex(option, opt, value):
    try:
        return complex(value)
    except ValueError:
        raise OptionValueError(
            "option %s: invalid complex value: %r" % (opt, value))

در نهایت، زیرکلاس Option:

class MyOption (Option):
    TYPES = Option.TYPES + ("complex",)
    TYPE_CHECKER = copy(Option.TYPE_CHECKER)
    TYPE_CHECKER["complex"] = check_complex

(اگر یک copy() از Option.TYPE_CHECKER نمی‌ساختیم، در نهایت ویژگی TYPE_CHECKER کلاس Optionِ optparse را تغییر می‌دادیم. از آنجا که اینجا پایتون است، هیچ چیز جز ادب و عقل سلیم شما را از انجام این کار باز نمی‌دارد.)

همین است! اکنون می‌توانید اسکریپتی بنویسید که از نوع جدید گزینه درست مانند هر اسکریپت دیگری مبتنی بر optparse استفاده می‌کند، با این تفاوت که باید به OptionParser خود دستور دهید به جای Option از MyOption استفاده کند:

parser = OptionParser(option_class=MyOption)
parser.add_option("-c", type="complex")

به‌عنوان جایگزین، می‌توانید فهرست گزینه‌های خودتان را بسازید و آن را به OptionParser بدهید؛ اگر از add_option() به روش بالا استفاده نکنید، نیازی نیست به OptionParser بگویید از کدام کلاس گزینه استفاده کند:

option_list = [MyOption("-c", action="store", type="complex", dest="c")]
parser = OptionParser(option_list=option_list)

افزودن کنش‌های جدید

افزودن کنش‌های جدید کمی پیچیده‌تر است، زیرا باید بدانید که optparse چند دسته‌بندی برای کنش‌ها دارد:

کنش‌های "store"

کنش‌هایی که باعث می‌شوند optparse یک مقدار را در یک ویژگی از نمونه‌ی فعلی OptionValues ذخیره کند؛ این گزینه‌ها نیاز دارند که یک ویژگی dest به سازنده‌ی Option ارائه شود.

کنش‌های «نوع‌دار»

کنش‌هایی که یک مقدار را از خط فرمان می‌گیرند و انتظار دارند آن مقدار از یک نوع مشخص باشد؛ یا دقیق‌تر، رشته‌ای که بتوان آن را به یک نوع مشخص تبدیل کرد. این گزینه‌ها به یک ویژگی type برای سازنده‌ی Option نیاز دارند.

این‌ها مجموعه‌های همپوشان هستند: برخی از کنش‌های پیش‌فرض «store» عبارتند از "store"، "store_const"، "append" و "count"، در حالی که کنش‌های پیش‌فرض «typed» عبارتند از "store"، "append" و "callback".

هنگامی که یک اکشناضافه می‌کنید، باید آن را با فهرست کردنش در حداقل یکی از ویژگی‌های کلاس Option که در زیر آمده است دسته‌بندی کنید (همه فهرست‌هایی از رشته‌ها هستند):

Option.ACTIONS

تمام اکشن‌ها باید در ACTIONS فهرست شوند.

Option.STORE_ACTIONS

کنش‌های "store" همچنین در اینجا فهرست شده‌اند.

Option.TYPED_ACTIONS

کنش‌های "typed" علاوه بر این، در اینجا نیز فهرست‌شده‌اند.

Option.ALWAYS_TYPED_ACTIONS

اکشنی که همیشه یک نوع می‌پذیرند (یعنی گزینه‌های آن‌ها همیشه یک مقدار می‌پذیرند) علاوه بر این در اینجا فهرست شده‌اند. تنها اثر این امر این است که optparse نوع پیش‌فرض، "string"، را به گزینه‌های بدون نوع صریحی که اکشن آن‌ها در ALWAYS_TYPED_ACTIONS فهرست شده است، اختصاص می‌دهد.

برای پیاده‌سازی واقعی اکشن جدید خود، باید متد take_action() مربوط به Option را بازنویسی کنید و یک حالت اضافه کنید که اکشن شما را شناسایی کند.

برای مثال، بیایید یک اکشن "extend" اضافه کنیم. این شبیه اکشن استاندارد "append" است، اما به جای دریافت یک مقدار از خط فرمان و افزودن آن به یک فهرست موجود، "extend" چندین مقدار را در یک رشته‌ی جداشده با ویرگول دریافت می‌کند و یک فهرست موجود را با آن‌ها گسترش می‌دهد. یعنی، اگر --names یک گزینه‌ی "extend" از نوع "string" باشد، خط فرمان

--names=foo,bar --names blah --names ding,dong

منجر به یک فهرست می‌شود

["foo", "bar", "blah", "ding", "dong"]

باز هم یک زیرکلاس از Option تعریف می‌کنیم:

class MyOption(Option):

    ACTIONS = Option.ACTIONS + ("extend",)
    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)

    def take_action(self, action, dest, opt, value, values, parser):
        if action == "extend":
            lvalue = value.split(",")
            values.ensure_value(dest, []).extend(lvalue)
        else:
            Option.take_action(
                self, action, dest, opt, value, values, parser)

قابلیت‌های قابل‌توجه:

  • "extend" هم یک مقدار را در خط فرمان انتظار دارد و هم آن مقدار را جایی ذخیره می‌کند، بنابراین در هر دو STORE_ACTIONS و TYPED_ACTIONS قرار می‌گیرد.

  • برای اطمینان از اینکه optparse نوع پیش‌فرض "string" را به کنش‌های "extend" اختصاص می‌دهد، اکشن "extend" را نیز در ALWAYS_TYPED_ACTIONS قرار دادیم.

  • MyOption.take_action() فقط همین یک کنش جدید را پیاده‌سازی می‌کند و کنترل را برای کنش‌های استاندارد optparse به Option.take_action() بازمی‌گرداند.

  • values نمونه‌ای از کلاس optparse_parser.Values است که متد بسیار مفید ensure_value() را فراهم می‌کند. ensure_value() در اصل همان getattr() با یک سوپاپ اطمینان است؛ این متد به این صورت فراخوانی می‌شود

    values.ensure_value(attr, value)
    

    اگر ویژگی attr در values وجود نداشته باشد یا None باشد، ensure_value() ابتدا آن را روی value تنظیم می‌کند و سپس value را برمی‌گرداند. این برای کنش‌هایی مانند "extend"، "append" و "count" بسیار کاربردی است؛ همه‌ی این‌ها داده را در یک متغیر انباشته می‌کنند و انتظار دارند آن متغیر از نوع خاصی باشد (برای دو مورد اول یک فهرست، برای مورد آخر یک عدد صحیح). استفاده از ensure_value() به این معناست که اسکریپت‌هایی که از کنش شما استفاده می‌کنند، نیازی به نگرانی درباره‌ی تنظیم مقدار پیش‌فرض برای مقصدهای گزینه‌های مورد بحث ندارند؛ آن‌ها می‌توانند فقط مقدار پیش‌فرض را None باقی بگذارند و ensure_value() هنگام نیاز، آن را به‌درستی تنظیم می‌کند.

استثناها

exception optparse.OptionError

اگر یک نمونه Option با آرگومان‌های نامعتبر یا ناسازگار ایجاد شود، پرتاب می‌شود.

exception optparse.OptionConflictError

در صورتی که گزینه‌های متعارض به یک OptionParser اضافه شوند، پرتاب می‌شود.

exception optparse.OptionValueError

در صورت مواجهه با مقدار نامعتبر برای یک گزینه در خط فرمان، پرتاب می‌شود.

exception optparse.BadOptionError

در صورتی که گزینه‌ای نامعتبر در خط فرمان ارسال شود، پرتاب می‌شود.

exception optparse.AmbiguousOptionError

در صورتی که یک گزینه مبهم در خط فرمان ارسال شود، پرتاب می‌شود.