11

目前我的代码看起来像这样。它允许我解析我的程序脚本获取的多个参数。是否有更接近“最佳实践”的不同方式?我还没有看到实际使用输出的代码argparse,只看到如何设置它。

def useArguments():
    x = 0
    while x <= 5:
        if x == 0:                      
            if args.getweather != None:
                getWeather(args.getweather)
        if x == 1:
            if args.post != None:
                post(args.post)
        if x == 2:
            if args.custompost != None:
                custompost(args.custompost)
        if x == 3:
            if args.list != None:
                listAccounts(args.list)
        if x == 4:
            if args.add != None:
                addAccount(args.add[0])
        if x == 5:
            if args.edit != None:
                editAccount(args.edit[0])
        x = x + 1    


if __name__ == '__main__':

    updateConfig()

    parser = argparse.ArgumentParser(description='Post Yahoo weather to Twitter.', epilog="Report any bugs to example@email.com", prog='Program')

    parser.add_argument('-a', '--add', nargs=1, help='Add a new account. Use the desired account name as an argument.')
    parser.add_argument('-e', '--edit', nargs=1, choices=accountListSTR[:-1], help='Edit an account. Use the desired account name as an argument.')
    parser.add_argument('-g', '--getweather', nargs='*', choices=accountListSTR, help='Get weather and post here. Specify account(s) as argument. Use "all" for all accounts. If you specify multiple accounts, separate by a space NOT a comma.')
    parser.add_argument('-p', '--post', nargs='*', choices=accountListSTR, help='Post weather to Twitter. Specify account(s) as argument. Use "all" for all accounts. If you specify multiple accounts, separate by a space NOT a comma.')
    parser.add_argument('-c', '--custompost', nargs=2, help='Post a custom message. Specify an account then type the message. Make sure you use "" around the message. Use "all" for all accounts.')
    parser.add_argument('-l', '--list', action='store_const', const='all', help='List all accounts.')
    parser.add_argument('--version', action='version', version='%(prog)s 0.3.3')

    args = parser.parse_args()

    useArguments()
4

3 回答 3

11

您可以为参数提供自定义操作,我引用:

传递一个实现 Action API 的对象。最简单的方法是扩展 argparse.Action,提供适当的__call__ 方法。该__call__方法应接受四个参数:

  1. parser:包含此操作的 ArgumentParser 对象。
  2. 命名空间:将由 . 返回的命名空间对象parse_args()。大多数操作都会向该对象添加一个属性。
  3. values:关联的命令行参数,应用了任何类型转换。(类型转换使用 type 关键字参数指定add_argument()
  4. option_string:用于调用此操作的选项字符串。option_string 参数是可选的,如果操作与位置参数相关联,则该参数将不存在。
于 2010-08-11T03:36:46.803 回答
6

请参阅http://docs.python.org/library/argparse.html#sub-commands

处理子命令的一种特别有效的方法是将add_subparsers()方法的使用与调用结合起来,set_defaults()以便每个子解析器都知道它应该执行哪个 Python 函数。

简而言之:

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()

weather_parser = subparsers.add_parser('get-weather')
weather_parser.add_argument('--bar')
weather_parser.set_defaults(function=get_weather)  # !

args = parser.parse_args(['get-weather', '--bar', 'quux'])
print args.function(args)

在这里,我们为命令创建一个子解析器get-weather并将函数分配get_weather给它。

请注意,文档说关键字/属性已命名func,但它绝对function是从 argparse 1.1 开始的。

生成的代码有点太罗嗦了,所以我发布了一个小包“argh”,让事情变得更简单,例如:

parser = argparse.ArgumentParser()
add_commands(parser, [get_weather])
print dispatch(parser, ['get-weather', '--bar', 'quux'])

“Argh”可以做得更多,但我会让堆栈溢出来回答这个问题。:-)

于 2010-11-12T21:43:37.867 回答
4

除了--version非常常见的选项之外,您提供的操作最好被视为“子命令”。

我不知道 argparse 的细节,因为我还没有尝试过 Python 2.7,但你可以看看这个svn命令作为例子,这里有一些命令行的伪代码:

myprog [--version] <command> [<command opts>...]

在哪里<command>

add|edit|getweather|post|custompost|list

并且<command opts>是特定于该命令的选项。使用 optparse (类似),这意味着您的命令将args在调用时返回parse_args,允许您执行以下操作:

opts, args = parser.parse_args()
if opts.version:
    ...
else:
    getattr("do_" + args[0])(*args[1:])

我发现这种模式对调试特别有用,我可以从命令行提供对内部函数的访问,并传递各种参数进行测试。根据您自己的项目调整命令处理程序的选择。

于 2010-08-11T03:10:39.707 回答