我使用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!
答案 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
。这将返回它无法识别的参数列表。这是处理一种错误的便捷方式。
它还讨论了编写自己的error
和exit
方法。你不喜欢的错误通过这两种方法。更改这些的正确方法是子类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)