在Python中使用argparse处理无效参数

时间:2016-07-12 23:11:53

标签: python argparse

我使用argparse来解析命令行参数,默认情况下,在接收无效参数时,它会打印帮助消息并退出。是否可以在收到无效参数时自定义argparse的行为?

一般来说,我想要捕获所有无效的参数并对它们进行处理。我正在寻找类似的东西:

parser = argparse.ArgumentParser()
# add some arguments here
try:
    parser.parse_args()
except InvalidArgvsError, iae:
    print "handle this invalid argument '{arg}' my way!".format(arg=iae.get_arg())

所以我可以:

>> python example.py --invalid some_text
handle this invalid argument 'invalid' my way!

4 个答案:

答案 0 :(得分:3)

您可能想要使用parse_known_args,然后查看元组中的第二项以查看哪些参数未被理解。

那就是说,我相信这只会对额外的参数有所帮助,而不是具有无效值的预期参数。

答案 1 :(得分:2)

之前的一些问题:

Python argparse and controlling/overriding the exit status code

I want Python argparse to throw an exception rather than usage

可能更多。

argparse文档讨论了如何使用parse_known_args。这将返回它无法识别的参数列表。这是处理一种错误的便捷方式。

它还讨论了编写自己的errorexit方法。你不喜欢的错误通过这两种方法。更改这些的正确方法是子类ArgumentParser,尽管您可以修补现有的解析器。默认版本位于argparse.py文件的末尾,因此您可以研究它们的作用。

第三种选择是尝试/除Systemexit。

try:
    parser=argparse.ArgumentParser()
    args=parser.parse_args()
except SystemExit:
    exc = sys.exc_info()[1]
    print(exc)

这样,错误/退出仍然会产生错误消息(到sys.stderr),但你可以阻止退出并继续做其他事情。

1649:~/mypy$ python stack38340252.py -x
usage: stack38340252.py [-h]
stack38340252.py: error: unrecognized arguments: -x
2

早先的一个问题抱怨parser.error没有获得有关错误的更多信息;它只是获取格式化的消息:

def myerror(message):
    print('error message')
    print(message)

parser=argparse.ArgumentParser()
parser.error = myerror
args=parser.parse_args()

显示器

1705:~/mypy$ python stack38340252.py -x
error message
unrecognized arguments: -x

您可以解析该消息,以找出-x是无法识别的字符串。在对早期版本的改进中,它可以列出多个参数

1705:~/mypy$ python stack38340252.py foo -x abc -b
error message
unrecognized arguments: foo -x abc -b

查找self.error以查看可能触发错误消息的所有案例。如果您需要更多想法,请关注特定类型的错误。

===============

unrecognized arguments错误由parse_args生成,调用parse_known_args,如果extras不为空,则会引发此错误。因此,它的特殊信息是parse_known_args无法处理的字符串列表。

parse_known_args如果它self.error陷阱,则会调用ArgumentError。通常,这些是在特定参数(Action)出现问题时生成的。但_parse_known_args如果需要,则调用self.error缺少操作,或者如果存在互斥组错误。 choices type可能会产生不同的错误。

答案 2 :(得分:1)

您可以尝试子类化import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; public class GenieGo_AVRO_Parsing { String jsonStr = "{\"objectKey\":\"trx/Android/2016-05-27/15-03-59/c496555a-940d-46eb-bc6a-21ae265ddf27\"} {\"StatDataRequest\":{\"protocolVersion\":\"1\",\"platform\":\"Android\",\"format\":\"Detailed\",\"deviceid\":\"c496555a-940d-46eb-bc6a-21ae265ddf27\",\"stats\":{\"clientStat\":[{\"contentActionStat\":{\"progid\":\"481080bd93a0710e496335d9acceb6add1695e7b\",\"rating\":\"0\",\"vendor\":\"1 1 11AD3C 70\",\"vod\":\"false\",\"ppv\":\"false\",\"series\":\"true\",\"title\":\"Wienerschnitzel\",\"description\":\"Wienerschnitzel CEO Cynthia Galardi-Culpepper.\",\"recordDate\":\"2016-05-23T01:00:00Z\",\"channel\":\"11\",\"channel_name\":\"WTOL\",\"TMSID\":\"EP011584600112\",\"channel_minor\":\"65535\",\"hd\":\"false\",\"contentAction\":\"Downloading_Started\",\"clientMode\":\"UNKNOWN\",\"timestamp\":\"2016-05-26T02:44:43.511Z\"}},{\"contentActionStat\":{\"progid\":\"481080bd93a0710e496335d9acceb6add1695e7b\",\"rating\":\"0\",\"vendor\":\"1 1 11AD3C 70\",\"vod\":\"false\",\"ppv\":\"false\",\"series\":\"true\",\"title\":\"Wienerschnitzel\",\"description\":\"Wienerschnitzel CEO Cynthia Galardi-Culpepper.\",\"recordDate\":\"2016-05-23T01:00:00Z\",\"channel\":\"11\",\"channel_name\":\"WTOL\",\"TMSID\":\"EP011584600112\",\"channel_minor\":\"65535\",\"hd\":\"false\",\"contentAction\":\"Downloading_Finish\",\"clientMode\":\"UNKNOWN\",\"durationSeconds\":\"263\",\"timestamp\":\"2016-05-26T02:49:06.347Z\"}},{\"contentActionStat\":{\"progid\":\"481080bd93a0710e496335d9acceb6add1695e7b\",\"rating\":\"0\",\"vendor\":\"1 1 11AD3C 70\",\"vod\":\"false\",\"ppv\":\"false\",\"series\":\"true\",\"title\":\"Wienerschnitzel\",\"description\":\"Wienerschnitzel CEO Cynthia Galardi-Culpepper.\",\"recordDate\":\"2016-05-23T01:00:00Z\",\"channel\":\"11\",\"channel_name\":\"WTOL\",\"TMSID\":\"EP011584600112\",\"channel_minor\":\"65535\",\"hd\":\"false\",\"contentAction\":\"Downloading_Cancel\",\"clientMode\":\"UNKNOWN\",\"timestamp\":\"2016-05-26T02:49:06.349Z\"}},{\"contentActionStat\":{\"progid\":\"dcb1e7d2374d0c0fa35131dda7e9228421a07668\",\"rating\":\"0\",\"vendor\":\"1 1 11AD3C 71\",\"vod\":\"false\",\"ppv\":\"false\",\"series\":\"true\",\"title\":\"Golden Krust Caribbean Bakery & Grill\",\"description\":\"Golden Krust Caribbean Bakery & Grill CEO Lowell Hawthorne.\",\"recordDate\":\"2016-05-23T02:00:00Z\",\"channel\":\"11\",\"channel_name\":\"WTOL\",\"TMSID\":\"EP011584600113\",\"channel_minor\":\"65535\",\"hd\":\"false\",\"contentAction\":\"Downloading_Started\",\"clientMode\":\"UNKNOWN\",\"timestamp\":\"2016-05-26T02:49:16.382Z\"}},{\"contentActionStat\":{\"progid\":\"dcb1e7d2374d0c0fa35131dda7e9228421a07668\",\"rating\":\"0\",\"vendor\":\"1 1 11AD3C 71\",\"vod\":\"false\",\"ppv\":\"false\",\"series\":\"true\",\"title\":\"Golden Krust Caribbean Bakery & Grill\",\"description\":\"Golden Krust Caribbean Bakery & Grill CEO Lowell Hawthorne.\",\"recordDate\":\"2016-05-23T02:00:00Z\",\"channel\":\"11\",\"channel_name\":\"WTOL\",\"TMSID\":\"EP011584600113\",\"channel_minor\":\"65535\",\"hd\":\"false\",\"contentAction\":\"Downloading_Finish\",\"clientMode\":\"UNKNOWN\",\"durationSeconds\":\"254\",\"timestamp\":\"2016-05-26T02:53:30.368Z\"}},{\"contentActionStat\":{\"progid\":\"dcb1e7d2374d0c0fa35131dda7e9228421a07668\",\"rating\":\"0\",\"vendor\":\"1 1 11AD3C 71\",\"vod\":\"false\",\"ppv\":\"false\",\"series\":\"true\",\"title\":\"Golden Krust Caribbean Bakery & Grill\",\"description\":\"Golden Krust Caribbean Bakery & Grill CEO Lowell Hawthorne.\",\"recordDate\":\"2016-05-23T02:00:00Z\",\"channel\":\"11\",\"channel_name\":\"WTOL\",\"TMSID\":\"EP011584600113\",\"channel_minor\":\"65535\",\"hd\":\"false\",\"contentAction\":\"Downloading_Cancel\",\"clientMode\":\"UNKNOWN\",\"timestamp\":\"2016-05-26T02:53:30.373Z\"}}]}}}"; //Input JSON String json1 = jsonStr.substring(0, jsonStr.indexOf("}")+1); String json2 = jsonStr.substring(jsonStr.indexOf("}")+1); String out = "", header = ""; JSONObject json = new JSONObject(json1); header = header.concat(json.getString("objectKey")).concat("|"); json = new JSONObject(json2); JSONObject StatDataRequest = json.getJSONObject("StatDataRequest"); header = header.concat(StatDataRequest.getString("protocolVersion")).concat("|"); header = header.concat(StatDataRequest.getString("platform")).concat("|"); header = header.concat(StatDataRequest.getString("format")).concat("|"); header = header.concat(StatDataRequest.getString("deviceid")).concat("|"); JSONObject stats = StatDataRequest.getJSONObject("stats"); JSONArray clientStatArr = stats.getJSONArray("clientStat"); List<String> keyList = new ArrayList<String>(); keyList.add("progid"); keyList.add("gen1re"); keyList.add("rating"); keyList.add("vendor"); keyList.add("vod"); keyList.add("ppv"); keyList.add("series"); keyList.add("title"); keyList.add("description"); keyList.add("recordDate"); keyList.add("channel"); keyList.add("channel_name"); keyList.add("TMSID"); keyList.add("channel_minor"); keyList.add("hd"); keyList.add("contentAction"); keyList.add("clientMode"); keyList.add("timestamp"); keyList.add("errorReason"); String row; JSONObject clientStat, contentActionStat; for (int i = 0; i < clientStatArr.length(); i++) { clientStat = clientStatArr.getJSONObject(i); contentActionStat = clientStat.getJSONObject("contentActionStat"); row = ""; for (String key : keyList) { row = row.concat(contentActionStat.getString(key)).concat("|"); } out = out.concat(header).concat(row).concat("\n"); } System.out.println(out); } } )并覆盖argparse.ArgumentParser(方法。

来自argparse来源:

error

答案 3 :(得分:0)

由于错误代码2是为内部docker使用而保留的,我使用以下内容来解析docker容器内脚本中的参数:

ERROR_CODE = 1
class DockerArgumentParser(argparse.ArgumentParser):
    def error(self, message):
        """error(message: string)

    Prints a usage message incorporating the message to stderr and
    exits.

    If you override this in a subclass, it should not return -- it
    should either exit or raise an exception.

    Overrides error method of the parent class to exit with error code 1 since default value is
    reserved for internal docker usage
    """
    self.print_usage(sys.stderr)
    args = {'prog': self.prog, 'message': message}
    self.exit(ERROR_CODE, '%(prog)s: error: %(message)s\n' % args)