Làm thế nào để phân tích cú pháp nhiều lệnh con lồng nhau bằng cách sử dụng python argparse?


81

Tôi đang triển khai một chương trình dòng lệnh có giao diện như sau:

cmd [GLOBAL_OPTIONS] {command [COMMAND_OPTS]} [{command [COMMAND_OPTS]} ...]

Tôi đã xem qua tài liệu của argparse . Tôi có thể triển khai GLOBAL_OPTIONSdưới dạng đối số tùy chọn bằng cách sử dụng add_argumenttrong argparse. Và {command [COMMAND_OPTS]}sử dụng các lệnh con .

Từ tài liệu có vẻ như tôi chỉ có thể có một lệnh con. Nhưng như bạn thấy, tôi phải triển khai một hoặc nhiều lệnh con. Cách tốt nhất để phân tích cú pháp các đối số dòng lệnh như vậy là argparsegì?


1
Tôi không nghĩ đây là mục đích của các lệnh con. Từ tài liệu, nó nói rằng về bản chất, đây là để kiểm soát các chương trình con riêng biệt . Bạn đã xem xét các nhóm tranh luận chưa?
Chris

distutils ./setup.pycũng có giao diện CLI theo phong cách này, sẽ rất thú vị khi xem xét mã nguồn của chúng.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Câu trả lời:


26

Tôi đã nghĩ ra cùng một câu trả lời, và có vẻ như tôi đã có câu trả lời tốt hơn.

Giải pháp là chúng ta sẽ không chỉ lồng các subparser với một subparser khác, mà chúng ta có thể thêm subparser theo sau với một parser sau một subparser khác.

Mã cho bạn biết cách:

parent_parser = argparse.ArgumentParser(add_help=False)                                                                                                  
parent_parser.add_argument('--user', '-u',                                                                                                               
                    default=getpass.getuser(),                                                                                                           
                    help='username')                                                                                                                     
parent_parser.add_argument('--debug', default=False, required=False,                                                                                     
                           action='store_true', dest="debug", help='debug flag')                                                                         
main_parser = argparse.ArgumentParser()                                                                                                                  
service_subparsers = main_parser.add_subparsers(title="service",                                                                                         
                    dest="service_command")                                                                                                              
service_parser = service_subparsers.add_parser("first", help="first",                                                                                    
                    parents=[parent_parser])                                                                                                             
action_subparser = service_parser.add_subparsers(title="action",                                                                                         
                    dest="action_command")                                                                                                               
action_parser = action_subparser.add_parser("second", help="second",                                                                                     
                    parents=[parent_parser])                                                                                                             

args = main_parser.parse_args()   

Có, argparsekhông cho phép các dấu sao con lồng nhau. Nhưng tôi chỉ thấy họ sử dụng ở một nơi khác - trong một trường hợp thử nghiệm cho một vấn đề Python, bugs.python.org/issue14365
hpaulj

9
Điều này giả định rằng các lệnh có cấu trúc lồng nhau. Nhưng câu hỏi là yêu cầu các lệnh "song song"
augurar

25

@mgilson có một câu trả lời hay cho câu hỏi này. Nhưng vấn đề với việc tự tách sys.argv là tôi mất tất cả thông báo trợ giúp thú vị mà Argparse tạo ra cho người dùng. Vì vậy, tôi đã kết thúc việc này:

import argparse

## This function takes the 'extra' attribute from global namespace and re-parses it to create separate namespaces for all other chained commands.
def parse_extra (parser, namespace):
  namespaces = []
  extra = namespace.extra
  while extra:
    n = parser.parse_args(extra)
    extra = n.extra
    namespaces.append(n)

  return namespaces

argparser=argparse.ArgumentParser()
subparsers = argparser.add_subparsers(help='sub-command help', dest='subparser_name')

parser_a = subparsers.add_parser('command_a', help = "command_a help")
## Setup options for parser_a

## Add nargs="*" for zero or more other commands
argparser.add_argument('extra', nargs = "*", help = 'Other commands')

## Do similar stuff for other sub-parsers

Bây giờ sau khi phân tích cú pháp đầu tiên, tất cả các lệnh chuỗi được lưu trữ trong extra. Tôi phân tích lại nó trong khi nó không trống để lấy tất cả các lệnh được xâu chuỗi và tạo không gian tên riêng cho chúng. Và tôi nhận được chuỗi sử dụng đẹp hơn mà argparse tạo ra.


2
@Flavius, sau khi tôi nhận được namespacetừ trình phân tích cú pháp bằng cách gọi namespace = argparser.parse_args(), tôi gọi parse_extrabằng parsernamespace. extra_namespaces = parse_extra( argparser, namespace )
Vikas

Tôi nghĩ rằng tôi hiểu logic, nhưng những gì parsertrong mã mà bạn có. Tôi chỉ thấy nó được sử dụng để thêm extrađối số. Sau đó, bạn đề cập lại nó một lần nữa trong bình luận trên. Nó được cho là argparser?
jmlopez

@jmlopez vâng, đúng vậy argparser. Sẽ chỉnh sửa nó.
Vikas

1
Lưu ý rằng giải pháp này không thành công đối với các đối số tùy chọn dành riêng cho lệnh con. Xem giải pháp của tôi bên dưới ( stackoverflow.com/a/49977713/428542 ) để biết giải pháp thay thế.
MacFreek

1
Đây là một ví dụ về cách điều này không thành công. Thêm 3 dòng sau : parser_b = subparsers.add_parser('command_b', help='command_b help'); parser_b.add_argument('--baz', choices='XYZ', help='baz help'); options = argparser.parse_args(['--foo', 'command_a', 'command_b', '--baz', 'Z']); Điều này không thành công với một lỗi PROG: error: unrecognized arguments: --baz Z. Lý do là trong quá trình phân tích cú pháp của command_a, các đối số tùy chọn của command_bđã được phân tích cú pháp (và không xác định đối với cụm phân tích con của command_a).
MacFreek

14

parse_known_argstrả về không gian tên và danh sách các chuỗi không xác định. Điều này tương tự như extratrong câu trả lời đã chọn.

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
sub = parser.add_subparsers()
for i in range(1,4):
    sp = sub.add_parser('cmd%i'%i)
    sp.add_argument('--foo%i'%i) # optionals have to be distinct

rest = '--foo 0 cmd2 --foo2 2 cmd3 --foo3 3 cmd1 --foo1 1'.split() # or sys.argv
args = argparse.Namespace()
while rest:
    args,rest =  parser.parse_known_args(rest,namespace=args)
    print args, rest

sản xuất:

Namespace(foo='0', foo2='2') ['cmd3', '--foo3', '3', 'cmd1', '--foo1', '1']
Namespace(foo='0', foo2='2', foo3='3') ['cmd1', '--foo1', '1']
Namespace(foo='0', foo1='1', foo2='2', foo3='3') []

Một vòng lặp thay thế sẽ cung cấp cho mỗi subparser không gian tên riêng của nó. Điều này cho phép chồng chéo tên vị trí.

argslist = []
while rest:
    args,rest =  parser.parse_known_args(rest)
    argslist.append(args)

Hoạt động tốt. Tuy nhiên, có một lỗ hổng: nếu có một tùy chọn sai chính tả ở đâu đó (ví dụ rest = '--foo 0 cmd2 --foo2 2 --bar cmd3 --foo3 3 cmd1 --foo1 1'.split()), thì argparse sẽ kết thúc error: too few argumentsthay vì chỉ ra tùy chọn không hợp lệ. Điều này là do tùy chọn xấu sẽ được giữ nguyên restcho đến khi chúng ta hết các đối số lệnh.
Adrian W

Nhận xét # or sys.argvnên được # or sys.argv[1:].
Adrian W

5

Bạn luôn có thể tự mình phân chia dòng lệnh (tách sys.argvtheo tên lệnh của bạn), và sau đó chỉ chuyển phần tương ứng với lệnh cụ thể đến parse_args- Bạn thậm chí có thể sử dụng dòng lệnh tương tự Namespacebằng cách sử dụng từ khóa không gian tên nếu bạn muốn.

Nhóm dòng lệnh thật dễ dàng với itertools.groupby:

import sys
import itertools
import argparse    

mycommands=['cmd1','cmd2','cmd3']

def groupargs(arg,currentarg=[None]):
    if(arg in mycommands):currentarg[0]=arg
    return currentarg[0]

commandlines=[list(args) for cmd,args in intertools.groupby(sys.argv,groupargs)]

#setup parser here...
parser=argparse.ArgumentParser()
#...

namespace=argparse.Namespace()
for cmdline in commandlines:
    parser.parse_args(cmdline,namespace=namespace)

#Now do something with namespace...

chưa được kiểm tra


1
Cảm ơn mgilson. Đây là một giải pháp tốt cho câu hỏi của tôi, nhưng cuối cùng tôi đã làm nó hơi khác một chút. Tôi đã thêm một câu trả lời khác .
Vikas

1
Tốt sử dụng itertools.groupby()! Đây là cách tôi đã làm điều tương tự trước khi tôi biết về nó groupby().
kzyapkov

5

Cải thiện câu trả lời của @mgilson, tôi đã viết một phương pháp phân tích cú pháp nhỏ để chia argv thành các phần và đặt các giá trị của đối số của các lệnh vào hệ thống phân cấp của không gian tên:

import sys
import argparse


def parse_args(parser, commands):
    # Divide argv by commands
    split_argv = [[]]
    for c in sys.argv[1:]:
        if c in commands.choices:
            split_argv.append([c])
        else:
            split_argv[-1].append(c)
    # Initialize namespace
    args = argparse.Namespace()
    for c in commands.choices:
        setattr(args, c, None)
    # Parse each command
    parser.parse_args(split_argv[0], namespace=args)  # Without command
    for argv in split_argv[1:]:  # Commands
        n = argparse.Namespace()
        setattr(args, argv[0], n)
        parser.parse_args(argv, namespace=n)
    return args


parser = argparse.ArgumentParser()
commands = parser.add_subparsers(title='sub-commands')

cmd1_parser = commands.add_parser('cmd1')
cmd1_parser.add_argument('--foo')

cmd2_parser = commands.add_parser('cmd2')
cmd2_parser.add_argument('--foo')

cmd2_parser = commands.add_parser('cmd3')
cmd2_parser.add_argument('--foo')


args = parse_args(parser, commands)
print(args)

Nó hoạt động đúng, cung cấp trợ giúp lý luận tốt đẹp:

Đối với ./test.py --help:

usage: test.py [-h] {cmd1,cmd2,cmd3} ...

optional arguments:
  -h, --help        show this help message and exit

sub-commands:
  {cmd1,cmd2,cmd3}

Đối với ./test.py cmd1 --help:

usage: test.py cmd1 [-h] [--foo FOO]

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO

Và tạo một hệ thống phân cấp các không gian tên chứa các giá trị đối số:

./test.py cmd1 --foo 3 cmd3 --foo 4
Namespace(cmd1=Namespace(foo='3'), cmd2=None, cmd3=Namespace(foo='4'))

Xem lại mã của bạn ở trên, tôi đã gặp phải một vấn đề. Trên dòng 18, bạn tham chiếu đến split_argv[0]mà thực sự trống trong split_argv, bởi vì bạn thêm [c]vào split_argv(nội dung được đặt thành [[]]). Nếu bạn thay đổi dòng 7 thành split_argv = [], mọi thứ hoạt động như mong đợi.
HEADLESS_0NE

2
Tôi đã làm một số sửa lỗi hơn (một lần nữa) vào mã bạn chia sẻ (sửa chữa một số vấn đề tôi đã chạy vào) và kết thúc với điều này: gist.github.com/anonymous/f4be805fc3ff9e132eb1e1aa0b4f7d4b
HEADLESS_0NE

Câu trả lời này là khá tốt, bạn có thể xác định subparserđược sử dụng bằng cách thêm đích đến add_subparsersphương pháp stackoverflow.com/questions/8250010/...
wizebin

5

Giải pháp do @Vikas cung cấp không thành công đối với các đối số tùy chọn dành riêng cho lệnh con, nhưng phương pháp này hợp lệ. Đây là một phiên bản cải tiến:

import argparse

# create the top-level parser
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('--foo', action='store_true', help='foo help')
subparsers = parser.add_subparsers(help='sub-command help', dest='subparser_name')

# create the parser for the "command_a" command
parser_a = subparsers.add_parser('command_a', help='command_a help')
parser_a.add_argument('bar', type=int, help='bar help')

# create the parser for the "command_b" command
parser_b = subparsers.add_parser('command_b', help='command_b help')
parser_b.add_argument('--baz', choices='XYZ', help='baz help')

# parse some argument lists
argv = ['--foo', 'command_a', '12', 'command_b', '--baz', 'Z']
while argv:
    print(argv)
    options, argv = parser.parse_known_args(argv)
    print(options)
    if not options.subparser_name:
        break

Điều này sử dụng parse_known_argsthay vì parse_args. parse_argshủy bỏ ngay khi gặp phải đối số không xác định đối với subparser hiện tại,parse_known_args trả về chúng dưới dạng giá trị thứ hai trong bộ giá trị trả về. Trong cách tiếp cận này, các đối số còn lại được cấp lại cho trình phân tích cú pháp. Vì vậy, đối với mỗi lệnh, một Namespace mới được tạo.

Lưu ý rằng trong ví dụ cơ bản này, tất cả các tùy chọn toàn cục chỉ được thêm vào các tùy chọn đầu tiên Không gian tên, không cho các Không gian tên tiếp theo.

Cách tiếp cận này hoạt động tốt cho hầu hết các tình huống, nhưng có ba hạn chế quan trọng:

  • Không thể sử dụng cùng một đối số tùy chọn cho các lệnh con khác nhau, chẳng hạn như myprog.py command_a --foo=bar command_b --foo=bar.
  • Không thể sử dụng bất kỳ đối số vị trí có độ dài thay đổi nào với các lệnh con ( nargs='?'hoặc nargs='+'hoặcnargs='*' ).
  • Bất kỳ đối số đã biết nào đều được phân tích cú pháp mà không bị 'ngắt' ở lệnh mới. Ví dụ: PROG --foo command_b command_a --baz Z 12với mã trên, --baz Zsẽ được tiêu thụ bởi command_b, không phải bởi command_a.

Những hạn chế này là một hạn chế trực tiếp của argparse. Đây là một ví dụ đơn giản cho thấy những hạn chế của argparse -even khi sử dụng một lệnh con-:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('spam', nargs='?')
subparsers = parser.add_subparsers(help='sub-command help', dest='subparser_name')

# create the parser for the "command_a" command
parser_a = subparsers.add_parser('command_a', help='command_a help')
parser_a.add_argument('bar', type=int, help='bar help')

# create the parser for the "command_b" command
parser_b = subparsers.add_parser('command_b', help='command_b help')

options = parser.parse_args('command_a 42'.split())
print(options)

Điều này sẽ nâng cao error: argument subparser_name: invalid choice: '42' (choose from 'command_a', 'command_b').

Nguyên nhân là do phương thức bên trong argparse.ArgParser._parse_known_args()nó quá tham lam và cho rằng đó command_alà giá trị của spamđối số tùy chọn . Đặc biệt, khi 'tách' các đối số tùy chọn và vị trí, _parse_known_args()không nhìn vào tên của các cung (như command_ahoặc command_b), mà chỉ nhìn vào vị trí chúng xuất hiện trong danh sách đối số. Nó cũng giả định rằng bất kỳ lệnh con nào sẽ sử dụng tất cả các đối số còn lại. Hạn chế này argparsecũng ngăn cản việc triển khai đúng các chương trình con đa lệnh. Điều này không may có nghĩa là việc triển khai đúng yêu cầu viết lại toàn bộ argparse.ArgParser._parse_known_args()phương thức, tức là hơn 200 dòng mã.

Với những hạn chế này, nó có thể là một tùy chọn để chỉ cần hoàn nguyên về một đối số nhiều lựa chọn thay vì các lệnh con:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--bar', type=int, help='bar help')
parser.add_argument('commands', nargs='*', metavar='COMMAND',
                 choices=['command_a', 'command_b'])

options = parser.parse_args('--bar 2 command_a command_b'.split())
print(options)
#options = parser.parse_args(['--help'])

Thậm chí có thể liệt kê các lệnh khác nhau trong thông tin sử dụng, hãy xem câu trả lời của tôi https://stackoverflow.com/a/49999185/428542


4

Bạn có thể thử arghandler . Đây là một phần mở rộng để lập luận với hỗ trợ rõ ràng cho các lệnh con.


3
arghandler cung cấp một cách hay để khai báo các lệnh con. Tuy nhiên, tôi không thấy cách này giúp giải quyết câu hỏi của OP: phân tích cú pháp nhiều lệnh con. Lệnh con đầu tiên được phân tích cú pháp sẽ ăn hết các đối số còn lại, vì vậy các lệnh tiếp theo sẽ không bao giờ được phân tích cú pháp. Vui lòng đưa ra một gợi ý về cách giải quyết vấn đề này với arghandler. Cảm ơn.
Adrian W

1

Một gói khác hỗ trợ các trình phân tích cú pháp song song là "explore_parser".

import argparse
from declarative_parser import Parser, Argument

supported_formats = ['png', 'jpeg', 'gif']

class InputParser(Parser):
    path = Argument(type=argparse.FileType('rb'), optional=False)
    format = Argument(default='png', choices=supported_formats)

class OutputParser(Parser):
    format = Argument(default='jpeg', choices=supported_formats)

class ImageConverter(Parser):
    description = 'This app converts images'

    verbose = Argument(action='store_true')
    input = InputParser()
    output = OutputParser()

parser = ImageConverter()

commands = '--verbose input image.jpeg --format jpeg output --format gif'.split()

namespace = parser.parse_args(commands)

và không gian tên trở thành:

Namespace(
    input=Namespace(format='jpeg', path=<_io.BufferedReader name='image.jpeg'>),
    output=Namespace(format='gif'),
    verbose=True
)

Disclaimer: Tôi là tác giả. Yêu cầu Python 3.6. Để cài đặt sử dụng:

pip3 install declarative_parser

Đây là tài liệu và đây là repo trên GitHub .


1

Xây dựng một đầy đủ Python 2/3 ví dụ với subparsers , parse_known_argsparse_args( chạy trên IDEone ):

from __future__ import print_function

from argparse import ArgumentParser
from random import randint


def main():
    parser = get_parser()

    input_sum_cmd = ['sum_cmd', '--sum']
    input_min_cmd = ['min_cmd', '--min']

    args, rest = parser.parse_known_args(
        # `sum`
        input_sum_cmd +
        ['-a', str(randint(21, 30)),
         '-b', str(randint(51, 80))] +
        # `min`
        input_min_cmd +
        ['-y', str(float(randint(64, 79))),
         '-z', str(float(randint(91, 120)) + .5)]
    )

    print('args:\t ', args,
          '\nrest:\t ', rest, '\n', sep='')

    sum_cmd_result = args.sm((args.a, args.b))
    print(
        'a:\t\t {:02d}\n'.format(args.a),
        'b:\t\t {:02d}\n'.format(args.b),
        'sum_cmd: {:02d}\n'.format(sum_cmd_result), sep='')

    assert rest[0] == 'min_cmd'
    args = parser.parse_args(rest)
    min_cmd_result = args.mn((args.y, args.z))
    print(
        'y:\t\t {:05.2f}\n'.format(args.y),
        'z:\t\t {:05.2f}\n'.format(args.z),
        'min_cmd: {:05.2f}'.format(min_cmd_result), sep='')

def get_parser():
    # create the top-level parser
    parser = ArgumentParser(prog='PROG')
    subparsers = parser.add_subparsers(help='sub-command help')

    # create the parser for the "sum" command
    parser_a = subparsers.add_parser('sum_cmd', help='sum some integers')
    parser_a.add_argument('-a', type=int,
                          help='an integer for the accumulator')
    parser_a.add_argument('-b', type=int,
                          help='an integer for the accumulator')
    parser_a.add_argument('--sum', dest='sm', action='store_const',
                          const=sum, default=max,
                          help='sum the integers (default: find the max)')

    # create the parser for the "min" command
    parser_b = subparsers.add_parser('min_cmd', help='min some integers')
    parser_b.add_argument('-y', type=float,
                          help='an float for the accumulator')
    parser_b.add_argument('-z', type=float,
                          help='an float for the accumulator')
    parser_b.add_argument('--min', dest='mn', action='store_const',
                          const=min, default=0,
                          help='smallest integer (default: 0)')
    return parser


if __name__ == '__main__':
    main()

0

Tôi đã có ít nhiều yêu cầu giống nhau: Có thể thiết lập các đối số toàn cục và có thể xâu chuỗi các lệnh và thực thi chúng theo thứ tự dòng lệnh .

Tôi đã kết thúc với mã sau đây. Tôi đã sử dụng một số phần của mã từ chuỗi này và các chuỗi khác.

# argtest.py
import sys
import argparse

def init_args():

    def parse_args_into_namespaces(parser, commands):
        '''
        Split all command arguments (without prefix, like --) in
        own namespaces. Each command accepts extra options for
        configuration.
        Example: `add 2 mul 5 --repeat 3` could be used to a sequencial
                 addition of 2, then multiply with 5 repeated 3 times.
        '''
        class OrderNamespace(argparse.Namespace):
            '''
            Add `command_order` attribute - a list of command
            in order on the command line. This allows sequencial
            processing of arguments.
            '''
            globals = None
            def __init__(self, **kwargs):
                self.command_order = []
                super(OrderNamespace, self).__init__(**kwargs)

            def __setattr__(self, attr, value):
                attr = attr.replace('-', '_')
                if value and attr not in self.command_order:
                    self.command_order.append(attr)
                super(OrderNamespace, self).__setattr__(attr, value)

        # Divide argv by commands
        split_argv = [[]]
        for c in sys.argv[1:]:
            if c in commands.choices:
                split_argv.append([c])
            else:
                split_argv[-1].append(c)

        # Globals arguments without commands
        args = OrderNamespace()
        cmd, args_raw = 'globals', split_argv.pop(0)
        args_parsed = parser.parse_args(args_raw, namespace=OrderNamespace())
        setattr(args, cmd, args_parsed)

        # Split all commands to separate namespace
        pos = 0
        while len(split_argv):
            pos += 1
            cmd, *args_raw = split_argv.pop(0)
            assert cmd[0].isalpha(), 'Command must start with a letter.'
            args_parsed = commands.choices[cmd].parse_args(args_raw, namespace=OrderNamespace())
            setattr(args, f'{cmd}~{pos}', args_parsed)

        return args


    #
    # Supported commands and options
    #
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    parser.add_argument('--print', action='store_true')

    commands = parser.add_subparsers(title='Operation chain')

    cmd1_parser = commands.add_parser('add', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    cmd1_parser.add_argument('add', help='Add this number.', type=float)
    cmd1_parser.add_argument('-r', '--repeat', help='Repeat this operation N times.',
                                               default=1, type=int)

    cmd2_parser = commands.add_parser('mult', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    cmd2_parser.add_argument('mult', help='Multiply with this number.', type=float)
    cmd2_parser.add_argument('-r', '--repeat', help='Repeat this operation N times.',
                                               default=1, type=int)

    args = parse_args_into_namespaces(parser, commands)
    return args


#
# DEMO
#

args = init_args()

# print('Parsed arguments:')
# for cmd in args.command_order:
#     namespace = getattr(args, cmd)
#     for option_name in namespace.command_order:
#         option_value = getattr(namespace, option_name)
#         print((cmd, option_name, option_value))

print('Execution:')
result = 0
for cmd in args.command_order:
    namespace = getattr(args, cmd)
    cmd_name, cmd_position = cmd.split('~') if cmd.find('~') > -1 else (cmd, 0)
    if cmd_name == 'globals':
        pass
    elif cmd_name == 'add':
        for r in range(namespace.repeat):
            if args.globals.print:
                print(f'+ {namespace.add}')
            result = result + namespace.add
    elif cmd_name == 'mult':
        for r in range(namespace.repeat):
            if args.globals.print:
                print(f'* {namespace.mult}')
            result = result * namespace.mult
    else:
        raise NotImplementedError(f'Namespace `{cmd}` is not implemented.')
print(10*'-')
print(result)

Dưới đây là một ví dụ:

$ python argstest.py --print add 1 -r 2 mult 5 add 3 mult -r 5 5

Execution:
+ 1.0
+ 1.0
* 5.0
+ 3.0
* 5.0
* 5.0
* 5.0
* 5.0
* 5.0
----------
40625.0

-4

bạn có thể sử dụng gói tùy chọn

import optparse
parser = optparse.OptionParser()
parser.add_option("-f", dest="filename", help="corpus filename")
parser.add_option("--alpha", dest="alpha", type="float", help="parameter alpha", default=0.5)
(options, args) = parser.parse_args()
fname = options.filename
alpha = options.alpha

1
Điều này không thực sự trả lời câu hỏi. Ngoài ra, optparse không được dùng nữa (từ tài liệu python "Mô-đun optparse không được dùng nữa và sẽ không được phát triển thêm; sự phát triển sẽ tiếp tục với mô-đun argparse").
Chris

Xin lỗi vì đã phản đối, nhưng điều này không giải quyết được câu hỏi tôi đã hỏi.
Vikas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.