【问题标题】:How can I make a Python script parse command line arguments like a Unix command? [duplicate]如何让 Python 脚本像 Unix 命令一样解析命令行参数? [复制]
【发布时间】:2013-11-08 17:11:08
【问题描述】:

我有一个 Python 实用程序脚本,它在命令行中接受参数并针对名为 Elasticsearch 的开源搜索工具执行任务。

但简单地说,这是它目前的使用方式:

Myscript.py create indexname http://localhost:9260
Myscript.py create indexname http://localhost:9260 IndexMap.json

我想让脚本的用户不必记住脚本参数的顺序。如何在我的脚本中启用它?我在考虑类似 Unix 的参数传递。例如:

import os
import sys
import glob
import subprocess 

# collect command line arguments
commandline_args = sys.argv

# How to use this simple API:
#   create indexname http://localhost:9260 IndexMap.json

command_type = commandline_args[1]
index_name = commandline_args[2]
base_elasticsearch_url = commandline_args[3]
file_to_index = sys.argv[4] if len(sys.argv) > 4 else None


def run_curl(command, url):
    cmd = ['curl', command]
    url = url.split(' ')
    print 'sending command: '
    print cmd+url    
    return subprocess.check_output(cmd+url)

if (command_type == 'delete'):
    print 'About to run '+ command_type + ' on Index: ' + index_name
    command = '-XDELETE'
    composed_url = base_elasticsearch_url + '/' + index_name + '/'
    output = run_curl(command, composed_url)
    print 'output:'
    print output

# create Index # works!
# curl -XPOST 'localhost:9260/icrd_client_1 -d @clientmappings.json
if (command_type == 'create'):
    print 'About to run '+command_type+' for Index: '+index_name+' from filename: '+file_to_index
    command = '-XPOST'
    composed_url = base_elasticsearch_url + '/' + index_name +' -d ' + '@'+file_to_index
    output = run_curl(command, composed_url)
    print 'output:'
    print output

【问题讨论】:

  • import argparse 将是一个不错的起点。
  • @sweeneyrod argparse 需要 2.7 或更高版本。

标签: python subprocess sys os.walk


【解决方案1】:

如果您使用的是 Python 2.7 或更新版本,请尝试argparse。对于旧版本,请尝试optparse

【讨论】:

  • 我有 python: 2.7.5。 argparse 看起来像一个非常笨重的猛犸象。你能提供一个例子来说明我如何在我的代码中使用它吗?我还需要 sys.argv 吗?
  • 我不明白“argparse 看起来像一只非常笨重的猛犸象”的评论。你能说得更具体点吗?
  • 好吧,我真正的问题是是否有更好的教程可以用于 argparse。python 网站上的那个是参考,我不是 python 专家。有没有关于这个主题的快速简单教程?
  • this tutorial 更有帮助吗?
  • args = parser.parse_args() command_type = commandline_args[1].. 我不了解 parser.parse_args()..
【解决方案2】:

我会建议一个使用 python 字典的简单优雅的解决方案,你可以使用字典 key 而不是使用 if 语句,这不是最好的选择,我相信它只是更优雅一点。

import sys

def func1():
    print "I'm func1"

def func2():
    print "I'm func2"

def func3():
    print "I'm func3"

def func4():
    print "I'm default!"

def main():

    myCommandDict = {"arg1": func1(), "arg2": func2(), "arg3": func3(), "default": func4()}

    commandline_args = sys.argv

    for argument in commandline_args[1]:
        if argument in myCommandDict:
            myCommandDict[argument]
        else:
            myCommandDict["default"]

if __name__ == "__main__":
    main()

Edit main 可以用这个选项代替:

myCommandDict = {"arg1": func1, "arg2": func2, "arg3": func3, "default": func4}

commandline_args = sys.argv[1:]

for argument in commandline_args:
    if argument in myCommandDict:
        myCommandDict[argument]()
    else:
        myCommandDict["default"]()

【讨论】:

  • 这对我来说没有意义。您将函数调用作为字典中的值,因此您拥有的是{"arg1": None, "arg2": None, "arg3": None, "default": None}。我想你想要 "arg1: func1myCommandDict[argument]() 代替。此外,您可以使用 myCommandDict.get(argument, func4)() 而不是 if else 语句替换 "default" 键。
  • @sweeneyrod 它可以双向工作(经过测试),但我对您建议的另一个选项进行了编辑,我不得不说这是一种更好的方法。
【解决方案3】:

您也可以使用Getopt(它的工作方式类似于 GNU Getopt)

【讨论】:

    猜你喜欢
    • 2011-03-15
    • 2020-01-01
    • 1970-01-01
    • 2011-04-17
    • 2011-03-26
    • 2011-04-27
    • 2013-02-18
    • 2013-03-21
    相关资源
    最近更新 更多