web-dev-qa-db-ja.com

大文字と小文字を区別しないargparseの選択

argparse choices を大文字と小文字を区別しない方法でチェックすることは可能ですか?

import argparse
choices = ["win64", "win32"]
parser = argparse.ArgumentParser()
parser.add_argument("-p", choices=choices)
print(parser.parse_args(["-p", "Win32"]))

結果:

usage: choices.py [-h] [-p {win64,win32}]
choices.py: error: argument -p: invalid choice: 'Win32' (choose from 'win64','win32')
50
Peter

を使用して引数を小文字に変換します

type = lambda s : s.lower()

のために -pスイッチ。

コメントで chepner が指摘したように、str.lowerはすでに適切な関数です。ラムダラッパーは必ずしも必要ではなく、代わりに単純に使用できます

type = str.lower

直接。

67
5gon12eder

lowertypeを使用するのは、ケース情報を失うことを気にしないのであれば、これを行う良い方法です。

ケースを保持したい場合は、カスタムchoicesクラスを定義できます。 choicesには、__contains__inのテスト用)、および反復(選択肢をリストするため)。

class mylist(list):
    # list subclass that uses lower() when testing for 'in'
    def __contains__(self, other):
        return super(mylist,self).__contains__(other.lower())
choices=mylist(['win64','win32'])
parser = argparse.ArgumentParser()
parser.add_argument("-p", choices=choices)
print(parser.parse_args(["-p", "Win32"]))
# Namespace(p='Win32')

ヘルプは次のとおりです。

usage: ipython [-h] [-p {win64,win32}]

optional arguments:
  -h, --help        show this help message and exit
  -p {win64,win32}
16
hpaulj

ケース情報を保持することも、1つのライナーで可能です。

type = lambda arg: {x.lower(): x for x in choices}[arg.lower()],

ここで、choicesは、choicesパラメーターに渡されたリストと同じです。

2
Andreas Walter