不区分大小写的argparse选项,而不会丢失选项列表中的大小写信息

时间:2019-07-01 15:03:25

标签: python python-3.x argparse ignore-case

我有一个very similar question,但是提供的解决方案不合适,因为我的用例略有不同。 为了简单起见,我将使我的问题适应已经回答的问题。

是否可以以不区分大小写的方式检查argparse choices而又不会丢失区分大小写的信息?

import argparse
choices = ["ADASYN", "BorderlineSMOTE", "KMeansSMOTE"]
parser = argparse.ArgumentParser()
parser.add_argument("-p", choices=choices)
print(parser.parse_args(["-p", "adasyn"]))

这导致:

choices.py: error: argument -p: invalid choice: 'adasyn' (choose from 'ADASYN', 'BorderlineSMOTE', 'KMeansSMOTE')

我显然可以使用 type.lower ,但是我的选择列表必须小写,并且-h(帮助输出)失去了很多可读性。另一方面,只要两个字符串.lower()相同,我希望用户能够使用不同的大小写。

@hpaulj的solution provided(类似问题)在我的情况下不起作用。它仅使参数输入具有任意大小写。因此,如果我的选择列表是小写的 AdAsyN 也可以,但是如果我将选择列表保留在CamelCase中,则选择列表中的大写字母也必须为大写字母。

有人对我有解决方案吗?我可以保留选择列表的大小写,而完全忽略用户输入的大小写?

1 个答案:

答案 0 :(得分:2)

您可以自定义类型功能以在选择列表中执行搜索,而不是简单的类型转换。这看起来有点黑,但可以。

def make_type(choices):
    def find_choice(choice):
        for key, item in enumerate([choice.lower() for choice in choices]):
            if choice.lower() == item:
                return choices[key]
        else:
            return choice
    return find_choice

choices = ["ADASYN", "BorderlineSMOTE", "KMeansSMOTE"]    
parser = argparse.ArgumentParser()
parser.add_argument("-p", choices=choices, type=make_type(choices))


print(parser.parse_args("-p adasyn".split()))
# Namespace(p='ADASYN')

print(parser.parse_args("-p ADASYN".split()))
# Namespace(p='ADASYN')

print(parser.parse_args("-p aDaSyN".split()))
# Namespace(p='ADASYN')

print(parser.parse_args("-p adasyn1".split()))
# usage: argsaction.py [-h] [-p {ADASYN,BorderlineSMOTE,KMeansSMOTE}]
# argsaction.py: error: argument -p: invalid choice: 'adasyn1' (choose from 'ADASYN', 'BorderlineSMOTE', 'KMeansSMOTE')

answer的关闭函数。
答案基于@hpaulj评论。