getopt --- پارسری به‌سبک C برای گزینه‌های خط فرمان

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

توجه

این ماژول از نظر قابلیت‌ها کامل تلقی می‌شود. جایگزینی اعلامی‌تر و توسعه‌پذیرتر برای این API در ماژول optparse ارائه شده است. بهبودهای کارکردی بیشتر برای پردازش پارامترهای خط فرمان یا به‌صورت ماژول‌های شخص ثالث در PyPI، یا به‌عنوان قابلیت‌هایی در ماژول argparse ارائه شده‌اند.


این ماژول به اسکریپت‌ها کمک می‌کند تا آرگومان‌های خط فرمان را در sys.argv تجزیه کنند. این ماژول از همان قراردادهای تابع getopt() یونیکس پشتیبانی می‌کند (از جمله معانی خاص آرگومان‌هایی با قالب '-' و '--'). همچنین می‌توان از طریق یک آرگومان سوم اختیاری، از گزینه‌های بلندی مشابه گزینه‌های پشتیبانی‌شده توسط نرم‌افزارهای GNU استفاده کرد.

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

این ماژول دو تابع و یک استثنا را فراهم می‌کند:

getopt.getopt(args, shortopts, longopts=[])

گزینه‌های خط فرمان و فهرست پارامترها را تجزیه می‌کند. args فهرست آرگومان‌هایی است که باید تجزیه شوند، بدون ارجاع ابتدایی به برنامه‌ی در حال اجرا. معمولاً این به معنای sys.argv[1:] است. shortopts رشته‌ای از حروف گزینه‌ها است که اسکریپت می‌خواهد آن‌ها را بشناسد، به‌طوری که گزینه‌های نیازمند آرگومان با یک علامت دونقطه (':') و گزینه‌هایی که آرگومان اختیاری می‌پذیرند با دو علامت دونقطه ('::') دنبال می‌شوند؛ یعنی همان قالبی که getopt() در یونیکس استفاده می‌کند.

توجه

برخلاف getopt() در GNU، پس از یک آرگومان غیرگزینه‌ای، تمام آرگومان‌های بعدی نیز غیرگزینه‌ای در نظر گرفته می‌شوند. این مشابه روش کار سیستم‌های یونیکس غیر GNU است.

longopts، در صورت مشخص بودن، باید فهرستی از رشته‌ها حاوی نام گزینه‌های بلندی باشد که باید پشتیبانی شوند. نویسه‌های '--' ابتدایی نباید در نام گزینه گنجانده شوند. گزینه‌های بلندی که به آرگومان نیاز دارند، باید به دنبال آن‌ها علامت برابر ('=') بیاید. گزینه‌های بلندی که آرگومان اختیاری می‌پذیرند، باید به دنبال آن‌ها علامت برابر و علامت سؤال ('=?') بیاید. برای پذیرش فقط گزینه‌های بلند، shortopts باید یک رشته خالی باشد. گزینه‌های بلند در خط فرمان تا زمانی قابل شناسایی هستند که پیشوندی از نام گزینه ارائه شود که دقیقاً با یکی از گزینه‌های پذیرفته‌شده مطابقت داشته باشد. برای مثال، اگر longopts برابر با ['foo', 'frob'] باشد، گزینه --fo به‌صورت --foo مطابقت خواهد داشت، اما --f به‌طور یکتا مطابقت نخواهد داشت، بنابراین GetoptError پرتاب خواهد شد.

اگر longopts یک رشته باشد، به‌عنوان فهرستی با یک عنصر در نظر گرفته می‌شود.

مقدار بازگشتی از دو عنصر تشکیل شده است: اولی فهرستی از جفت‌های (option, value) است؛ دومی فهرست آرگومان‌های برنامه باقی‌مانده پس از حذف فهرست گزینه‌ها است (این یک اسلایس انتهایی از args است). هر جفت گزینه-و-مقدار بازگشتی، گزینه را به‌عنوان اولین عنصر خود دارد؛ این گزینه با یک خط تیره برای گزینه‌های کوتاه (برای نمونه، '-x') یا دو خط تیره برای گزینه‌های بلند (برای نمونه، '--long-option') پیشوند داده شده است، و آرگومان گزینه را به‌عنوان عنصر دوم خود دارد، یا اگر گزینه آرگومانی نداشته باشد، عنصر دوم یک رشته‌ی خالی است. گزینه‌ها در فهرست به همان ترتیبی که پیدا شده‌اند ظاهر می‌شوند، بنابراین امکان تکرار آن‌ها وجود دارد. گزینه‌های بلند و کوتاه می‌توانند با هم ترکیب شوند.

تغییر یافته در نسخه‌ی 3.14: از آرگومان‌های اختیاری پشتیبانی می‌شود.

getopt.gnu_getopt(args, shortopts, longopts=[])

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

اگر نخستین نویسه‌ی رشته گزینه '+' باشد، یا اگر متغیر محیطی POSIXLY_CORRECT تنظیم شده باشد، پردازش گزینه‌ها به محض مواجهه با یک آرگومان غیرگزینه‌ای متوقف می‌شود.

اگر نخستین نویسه‌ی رشته‌ی گزینه‌ها '-' باشد، آرگومان‌های غیرگزینه‌ای که پس از آن‌ها گزینه‌ها می‌آیند، به فهرست جفت‌های گزینه و مقدار به‌صورت جفتی افزوده می‌شوند که عنصر نخست آن None و عنصر دوم آن فهرست آرگومان‌های غیرگزینه‌ای است. عنصر دوم نتیجه‌ی gnu_getopt() فهرستی از آرگومان‌های برنامه پس از آخرین گزینه است.

تغییر یافته در نسخه‌ی 3.14: پشتیبانی از بازگرداندن گزینه‌ها و آرگومان‌های غیرگزینه‌ای درهم‌آمیخته به‌ترتیب.

exception getopt.GetoptError

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

exception getopt.error

نام مستعاری برای GetoptError؛ برای سازگاری با نسخه‌های قدیمی.

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

>>> import getopt
>>> args = '-a -b -cfoo -d bar a1 a2'.split()
>>> args
['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'abc:d:')
>>> optlist
[('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')]
>>> args
['a1', 'a2']

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

>>> s = '--condition=foo --testing --output-file abc.def -x a1 a2'
>>> args = s.split()
>>> args
['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'x', [
...     'condition=', 'output-file=', 'testing'])
>>> optlist
[('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')]
>>> args
['a1', 'a2']

آرگومان‌های اختیاری باید به‌صراحت مشخص شوند:

>>> s = '-Con -C --color=off --color a1 a2'
>>> args = s.split()
>>> args
['-Con', '-C', '--color=off', '--color', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'C::', ['color=?'])
>>> optlist
[('-C', 'on'), ('-C', ''), ('--color', 'off'), ('--color', '')]
>>> args
['a1', 'a2']

می‌توان ترتیب گزینه‌ها و آرگومان‌های غیرگزینه‌ای را حفظ کرد:

>>> s = 'a1 -x a2 a3 a4 --long a5 a6'
>>> args = s.split()
>>> args
['a1', '-x', 'a2', 'a3', 'a4', '--long', 'a5', 'a6']
>>> optlist, args = getopt.gnu_getopt(args, '-x:', ['long='])
>>> optlist
[(None, ['a1']), ('-x', 'a2'), (None, ['a3', 'a4']), ('--long', 'a5')]
>>> args
['a6']

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

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError as err:
        # print help information and exit:
        print(err)  # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        elif o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-o", "--output"):
            output = a
        else:
            assert False, "unhandled option"
    process(args, output=output, verbose=verbose)

if __name__ == "__main__":
    main()

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

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)

همچنین می‌توان یک رابط خط فرمان تقریباً معادل برای این حالت را با استفاده از ماژول argparse ایجاد کرد:

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)

برای جزئیات درباره‌ی اینکه نسخه‌ی argparse این کد از نظر رفتار چه تفاوتی با نسخه‌ی optparsegetopt) دارد، انتخاب یک کتابخانه تجزیه آرگومان را ببینید.

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

ماژول optparse

تجزیه‌ی اعلامی گزینه‌های خط فرمان.

ماژول argparse

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