سؤال

ما أسهل, tersest, و أكثر مرنة طريقة أو مكتبة تحليل بايثون سطر الأوامر الحجج ؟

هل كانت مفيدة؟

المحلول

هذا الجواب يشير إلى optparse والتي هي مناسبة لكبار السن من إصدارات بيثون.بايثون 2.7 وما فوق ، argparse يستبدل optparse.انظر هذا الجواب للحصول على مزيد من المعلومات.

و أشار كنت أفضل حالا الذهاب مع optparse على getopt.getopt حد كبير واحد-إلى-واحد الخرائط القياسية getopt(3) ج وظائف المكتبة ، وليس من السهل جدا للاستخدام.

optparse ، في حين يجري قليلا أكثر مطول, هو أفضل بكثير منظم و أبسط إلى تمديد في وقت لاحق.

وهنا نموذجية خط لإضافة خيار إلى محلل:

parser.add_option('-q', '--query',
            action="store", dest="query",
            help="query string", default="spam")

فهذا يتحدث عن نفسه ؛ في وقت المعالجة ، فإنه لن يقبل -q أو الاستعلام الخيارات متجر حجة في سمة يسمى استعلام يحتوي على قيمة افتراضية إذا كنت لا تحديد في ذلك.بل هو أيضا توثيق عن النفس في ذلك تعلن مساعدة الحجة (التي سيتم استخدامها عند تشغيل مع -h/--help) هناك مع الخيار.

عادة لتحليل الحجج الخاصة بك مع:

options, args = parser.parse_args()

هذا بشكل افتراضي تحليل الحجج القياسية التي تم تمريرها إلى البرنامج النصي (sys.argv[1:])

خيارات.الاستعلام ثم سيتم تعيين إلى القيمة التي تم تمريرها إلى البرنامج النصي.

يمكنك إنشاء محلل ببساطة عن طريق القيام

parser = optparse.OptionParser()

هذه هي الأساسيات التي تحتاج إليها.هنا كامل بيثون السيناريو الذي يبين هذا:

import optparse

parser = optparse.OptionParser()

parser.add_option('-q', '--query',
    action="store", dest="query",
    help="query string", default="spam")

options, args = parser.parse_args()

print 'Query string:', options.query

5 خطوط من بيثون التي تظهر لك الأساسيات.

حفظه في sample.py تشغيل مرة واحدة مع

python sample.py

ومرة واحدة مع

python sample.py --query myquery

أبعد من ذلك, سوف تجد أن optparse من السهل جدا أن تمتد.في واحدة من بلدي المشاريع, أنا خلقت قيادة الطبقة التي تسمح لك عش subcommands في أمر الشجرة بسهولة.ويستخدم optparse بشكل كبير إلى سلسلة من الأوامر معا.إنه شيء لا يمكن أن تفسر بسهولة في بضعة أسطر, ولكن لا تتردد في تصفح في مستودع على الطبقة الرئيسية ، وكذلك فئة يستخدم هذا الخيار محلل

نصائح أخرى

إجابات أخرى لا أذكر أن argparse هو الطريق للذهاب جديدة الثعبان, ولكن لا تعطي أمثلة الاستخدام.عن اكتمال هنا هو موجز قصير عن كيفية استخدام argparse:

1) تهيئة

import argparse

# Instantiate the parser
parser = argparse.ArgumentParser(description='Optional app description')

2) إضافة الحجج

# Required positional argument
parser.add_argument('pos_arg', type=int,
                    help='A required integer positional argument')

# Optional positional argument
parser.add_argument('opt_pos_arg', type=int, nargs='?',
                    help='An optional integer positional argument')

# Optional argument
parser.add_argument('--opt_arg', type=int,
                    help='An optional integer argument')

# Switch
parser.add_argument('--switch', action='store_true',
                    help='A boolean switch')

3) تحليل

args = parser.parse_args()

4) الوصول

print("Argument values:")
print(args.pos_arg)
print(args.opt_pos_arg)
print(args.opt_arg)
print(args.switch)

5) التحقق من القيم

if args.pos_arg > 10:
    parser.error("pos_arg cannot be larger than 10")

الاستخدام

الاستخدام الصحيح:

$ ./app 1 2 --opt_arg 3 --switch

Argument values:
1
2
3
True

غير صحيحة الحجج:

$ ./app foo 2 --opt_arg 3 --switch
usage: convert [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
app: error: argument pos_arg: invalid int value: 'foo'

$ ./app 11 2 --opt_arg 3
Argument values:
11
2
3
False
usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
convert: error: pos_arg cannot be larger than 10

مساعدة كاملة:

$ ./app -h

usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]

Optional app description

positional arguments:
  pos_arg            A required integer positional argument
  opt_pos_arg        An optional integer positional argument

optional arguments:
  -h, --help         show this help message and exit
  --opt_arg OPT_ARG  An optional integer argument
  --switch           A boolean switch

باستخدام docopt

منذ عام 2012 الثعبان جدا سهلة وقوية حقا بارد وحدة حجة تحليل يسمى docopt.يعمل مع بيثون 2.6 3.5 و لا يحتاج إلى تثبيت (فقط نسخ ذلك).وفيما يلي مثال مأخوذ من الوثائق:

"""Naval Fate.

Usage:
  naval_fate.py ship new <name>...
  naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
  naval_fate.py ship shoot <x> <y>
  naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
  naval_fate.py (-h | --help)
  naval_fate.py --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  Speed in knots [default: 10].
  --moored      Moored (anchored) mine.
  --drifting    Drifting mine.

"""
from docopt import docopt


if __name__ == '__main__':
    arguments = docopt(__doc__, version='Naval Fate 2.0')
    print(arguments)

لذلك هذا هو:2 الأسطر من التعليمات البرمجية بالإضافة إلى doc السلسلة التي هو أساسي على تحليل الحجج المتاحة في الحجج وجوه.قلت لك إنه رائع, أليس كذلك ;-)

باستخدام بيثون-النار

منذ عام 2017 بيثون-النار آخر بارد الوحدة التي يمكن أن تعطي CLI واجهة التعليمات البرمجية الخاصة بك مع حالك صفر حجة تحليل.وهنا مثال بسيط من الوثائق (هذا برنامج صغير يعرض وظيفة double إلى سطر الأوامر):

import fire

class Calculator(object):

  def double(self, number):
    return 2 * number

if __name__ == '__main__':
  fire.Fire(Calculator)

من سطر الأوامر, يمكنك تشغيل:

> calculator.py double 10
20
> calculator.py double --number=15
30

رائع أليس كذلك ؟

الورك الجديد طريقة argparse بالنسبة هذه الأسباب.argparse > optparse > getopt

تحديث: كما من py2.7 argparse هو جزء من المكتبة القياسية ، optparse هو إهمال.

أنا أفضل انقر.فإنه ملخصات إدارة خيارات يسمح "(...) خلق جميلة سطر الأوامر واجهات في composable الطريقة مع القليل من قانون الضرورة".

هنا هو مثال على الاستخدام:

import click

@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
              help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo('Hello %s!' % name)

if __name__ == '__main__':
    hello()

كما يولد تلقائيا تنسيق جيد صفحات المساعدة:

$ python hello.py --help
Usage: hello.py [OPTIONS]

  Simple program that greets NAME for a total of COUNT times.

Options:
  --count INTEGER  Number of greetings.
  --name TEXT      The person to greet.
  --help           Show this message and exit.

تقريبا كل شخص يستخدم getopt

هنا هو مثال رمز الوثيقة :

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        if o in ("-o", "--output"):
            output = a

وذلك في كلمة هنا هو كيف يعمل.

لديك نوعين من الخيارات.أولئك الذين يتلقون الحجج ، وأولئك الذين هم مثل التبديل.

sys.argv هو تقريبا char** argv في C.في مثل C يمكنك تخطي العنصر الأول الذي هو اسم البرنامج و تحليل فقط الحجج : sys.argv[1:]

Getopt.getopt سوف تحليل ذلك وفقا لقاعدة كنت تعطي في الحجة.

"ho:v" هنا يصف قصيرة الحجج : -ONELETTER.على : يعني -o تقبل حجة واحدة.

أخيرا ["help", "output="] يصف طويلة الحجج ( --MORETHANONELETTER ).على = بعد الإخراج مرة أخرى يعني أن الناتج يقبل أحد الحجج.

والنتيجة هي قائمة من الزوجين (الخيار ، حجة)

إذا كان الخيار لا يقبل أي حجة (مثل --help هنا) arg جزء من سلسلة فارغة.ثم عادة ما ترغب في حلقة في هذه القائمة واختبار اسم الخيار كما في المثال.

آمل أن يكون هذا ساعد لك.

استخدام optparse الذي يأتي مع مكتبة القياسية.على سبيل المثال:

#!/usr/bin/env python
import optparse

def main():
  p = optparse.OptionParser()
  p.add_option('--person', '-p', default="world")
  options, arguments = p.parse_args()
  print 'Hello %s' % options.person

if __name__ == '__main__':
  main()

المصدر: باستخدام بيثون لخلق UNIX أدوات سطر الأوامر

ومع ذلك اعتبارا من بايثون 2.7 optparse هو مستنكر ، انظر: لماذا استخدام argparse بدلا من optparse?

فقط في حال كنت قد تحتاج إلى أن هذا قد يساعد إذا كنت بحاجة إلى الاستيلاء على unicode الحجج على Win32 (2K, XP الخ):


from ctypes import *

def wmain(argc, argv):
    print argc
    for i in argv:
        print i
    return 0

def startup():
    size = c_int()
    ptr = windll.shell32.CommandLineToArgvW(windll.kernel32.GetCommandLineW(), byref(size))
    ref = c_wchar_p * size.value
    raw = ref.from_address(ptr)
    args = [arg for arg in raw]
    windll.kernel32.LocalFree(ptr)
    exit(wmain(len(args), args))
startup()

خفيفة الوزن وسيطة سطر الأوامر التخلف

على الرغم من أن argparse كبيرة و هي الإجابة الصحيحة على الموثقة بالكامل رموز تبديل سطر الأوامر والميزات المتقدمة ، يمكنك استخدام وظيفة حجة التخلف إلى مقابض مباشرة الموضعية الحجج ببساطة جدا.

import sys

def get_args(name='default', first='a', second=2):
    return first, int(second)

first, second = get_args(*sys.argv)
print first, second

"الاسم" حجة يلتقط اسم البرنامج النصي وليس استخدامها.اختبار الإخراج يبدو مثل هذا:

> ./test.py
a 2
> ./test.py A
A 2
> ./test.py A 20
A 20

عن "البرامج النصية بسيطة" حيث أريد فقط بعض القيم الافتراضية ، أجد هذا كافيا جدا.قد ترغب أيضا في أن تشمل بعض نوع الإكراه في عودة القيم أو سطر الأوامر القيم سوف تكون جميع السلاسل.

أعتقد أن أفضل طريقة للحصول على أكبر المشاريع optparse, ولكن إذا كنت تبحث عن طريقة سهلة ربما http://werkzeug.pocoo.org/documentation/script هو شيء بالنسبة لك.

from werkzeug import script

# actions go here
def action_foo(name=""):
    """action foo does foo"""
    pass

def action_bar(id=0, title="default title"):
    """action bar does bar"""
    pass

if __name__ == '__main__':
    script.run()

وذلك أساسا كل وظيفة action_* يتعرض إلى سطر الأوامر و لطيفة تساعد يتم إنشاء رسالة مجانا.

python foo.py 
usage: foo.py <action> [<options>]
       foo.py --help

actions:
  bar:
    action bar does bar

    --id                          integer   0
    --title                       string    default title

  foo:
    action foo does foo

    --name                        string

أنا أفضل optparse إلى getopt.انها جدا التعريفي:كنت أقول أسماء خيارات والآثار التي ينبغي أن يكون (على سبيل المثال ، وضع حقل منطقي) ، يد لك مرة أخرى القاموس بالسكان وفقا للمواصفات الخاصة بك.

http://docs.python.org/lib/module-optparse.html

consoleargs يستحق الذكر هنا.فمن السهل جدا للاستخدام.التحقق من ذلك:

from consoleargs import command

@command
def main(url, name=None):
  """
  :param url: Remote URL 
  :param name: File name
  """
  print """Downloading url '%r' into file '%r'""" % (url, name)

if __name__ == '__main__':
  main()

الآن في وحدة التحكم:

% python demo.py --help
Usage: demo.py URL [OPTIONS]

URL:    Remote URL 

Options:
    --name -n   File name

% python demo.py http://www.google.com/
Downloading url ''http://www.google.com/'' into file 'None'

% python demo.py http://www.google.com/ --name=index.html
Downloading url ''http://www.google.com/'' into file ''index.html''

Argparse رمز يمكن أن تكون أطول من التنفيذ الفعلي رمز!

هذه مشكلة أجد مع الأكثر شعبية حجة تحليل الخيارات هو أنه إذا كان لديك المعلمات متواضعة فقط ، رمز الوثيقة تصبح كبيرة بشكل غير متناسب إلى الفائدة التي يقدمونها.

قريب الوافد الجديد إلى حجة تحليل المشهد (على ما أظن) ، plac.

فإنه يجعل بعض اعترف المقايضات مع argparse ولكن يستخدم وثائق مضمنة و يلتف حول ببساطة main() وظيفة نوع الوظيفة:

def main(excel_file_path: "Path to input training file.",
     excel_sheet_name:"Name of the excel sheet containing training data including columns 'Label' and 'Description'.",
     existing_model_path: "Path to an existing model to refine."=None,
     batch_size_start: "The smallest size of any minibatch."=10.,
     batch_size_stop:  "The largest size of any minibatch."=250.,
     batch_size_step:  "The step for increase in minibatch size."=1.002,
     batch_test_steps: "Flag.  If True, show minibatch steps."=False):
"Train a Spacy (http://spacy.io/) text classification model with gold document and label data until the model nears convergence (LOSS < 0.5)."

    pass # Implementation code goes here!

if __name__ == '__main__':
    import plac; plac.call(main)

هنا هو وسيلة وليس مكتبة ، التي يبدو أن العمل بالنسبة لي.

الأهداف هنا هي أن تكون مقتضب كل حجة تحليل خط واحد ، وسائط خط القراءة ، رمز بسيط و لا تعتمد على أي وحدات خاصة (فقط os + sys), يحذر مفقودة أو غير معروفة الحجج برشاقة, استخدام بسيط/مجموعة() حلقة ، ويعمل في بيثون 2.x و 3.x

يظهر نوعان من تبديل الأعلام (-د-ت) ، واثنين من القيم التي تسيطر عليها الحجج (أنا xxx -o xxx).

import os,sys

def HelpAndExit():
    print("<<your help output goes here>>")
    sys.exit(1)

def Fatal(msg):
    sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg))
    sys.exit(1)

def NextArg(i):
    '''Return the next command line argument (if there is one)'''
    if ((i+1) >= len(sys.argv)):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return(1, sys.argv[i+1])

### MAIN
if __name__=='__main__':

    verbose = 0
    debug   = 0
    infile  = "infile"
    outfile = "outfile"

    # Parse command line
    skip = 0
    for i in range(1, len(sys.argv)):
        if not skip:
            if   sys.argv[i][:2] == "-d": debug ^= 1
            elif sys.argv[i][:2] == "-v": verbose ^= 1
            elif sys.argv[i][:2] == "-i": (skip,infile)  = NextArg(i)
            elif sys.argv[i][:2] == "-o": (skip,outfile) = NextArg(i)
            elif sys.argv[i][:2] == "-h": HelpAndExit()
            elif sys.argv[i][:1] == "-":  Fatal("'%s' unknown argument" % sys.argv[i])
            else:                         Fatal("'%s' unexpected" % sys.argv[i])
        else: skip = 0

    print("%d,%d,%s,%s" % (debug,verbose,infile,outfile))

الهدف من NextArg() هو العودة المقبل حجة في حين التحقق من البيانات المفقودة ، 'تخطي' يتخطى حلقة عندما NextArg() يستخدم, حفظ العلم تحليل واحد المتشددين.

مددت Erco نهج تسمح المطلوبة الموضعية الحجج و وسيطات اختيارية.هذه ينبغي أن يسبق -د-v etc.الحجج.

الموضعية و وسيطات اختيارية يمكن استرجاعها مع PosArg(أنا) و OptArg(أنا الافتراضي) على التوالي.عند اختياري حجة وجدت موضع بداية من البحث عن الخيارات (على سبيل المثال-ط) يتم نقل 1 للمستقبل لتجنب حدوث "غير متوقعة" قاتلة.

import os,sys


def HelpAndExit():
    print("<<your help output goes here>>")
    sys.exit(1)

def Fatal(msg):
    sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg))
    sys.exit(1)

def NextArg(i):
    '''Return the next command line argument (if there is one)'''
    if ((i+1) >= len(sys.argv)):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return(1, sys.argv[i+1])

def PosArg(i):
    '''Return positional argument'''
    if i >= len(sys.argv):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return sys.argv[i]

def OptArg(i, default):
    '''Return optional argument (if there is one)'''
    if i >= len(sys.argv):
        Fatal("'%s' expected an argument" % sys.argv[i])
    if sys.argv[i][:1] != '-':
        return True, sys.argv[i]
    else:
        return False, default


### MAIN
if __name__=='__main__':

    verbose = 0
    debug   = 0
    infile  = "infile"
    outfile = "outfile"
    options_start = 3

    # --- Parse two positional parameters ---
    n1 = int(PosArg(1))
    n2 = int(PosArg(2))

    # --- Parse an optional parameters ---
    present, a3 = OptArg(3,50)
    n3 = int(a3)
    options_start += int(present)

    # --- Parse rest of command line ---
    skip = 0
    for i in range(options_start, len(sys.argv)):
        if not skip:
            if   sys.argv[i][:2] == "-d": debug ^= 1
            elif sys.argv[i][:2] == "-v": verbose ^= 1
            elif sys.argv[i][:2] == "-i": (skip,infile)  = NextArg(i)
            elif sys.argv[i][:2] == "-o": (skip,outfile) = NextArg(i)
            elif sys.argv[i][:2] == "-h": HelpAndExit()
            elif sys.argv[i][:1] == "-":  Fatal("'%s' unknown argument" % sys.argv[i])
            else:                         Fatal("'%s' unexpected" % sys.argv[i])
        else: skip = 0

    print("Number 1 = %d" % n1)
    print("Number 2 = %d" % n2)
    print("Number 3 = %d" % n3)
    print("Debug    = %d" % debug)
    print("verbose  = %d" % verbose)
    print("infile   = %s" % infile)
    print("outfile  = %s" % outfile) 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top