Регистърът не е чувствителен към избора на argparse

Възможно ли е да се проверят изборите на argparse без значение за малки и големи букви?

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')

person Peter    schedule 23.12.2014    source източник


Отговори (3)


Преобразувайте аргумента в малки букви, като използвате

type = str.lower

за превключвателя -p.

Това решение беше посочено от chepner в коментар. Решението, което предложих по-рано, беше

type = lambda s : s.lower()

което също е валидно, но е по-лесно просто да използвате str.lower.

person 5gon12eder    schedule 23.12.2014
comment
Можете да се отървете от ламбда като просто използвате type = str.lower, тъй като str.lower е функция, която взема низ и го връща с малки букви. - person chepner; 24.12.2014
comment
Тъй като функцията string.lower(s) беше отхвърлено и заменено с s.lower() метод, бих препоръчал ламбда подхода, както е предложен първоначално. - person Mark; 14.03.2017
comment
@Mark Нито една версия не използва отхвърлената функция от модула string. Обърнете внимание, че се използва str.lower (без ing), което е методът от класа str, вземащ self като единствен параметър, поради което трикът работи. - person 5gon12eder; 16.03.2017
comment
@5gon12eder Благодаря за вниманието, има смисъл! Добре е да се знае. Описанието на @chepner ме отблъсна, защото той каза, че това е функцията str.lower, която приема низ, което би означавало, че той има предвид вече остарялата функция, а не заместващата метод, който не приема никаква информация, но действа върху self. - person Mark; 17.03.2017
comment
obj.method(*args, **kwargs) в по-голямата си част е идентичен с type(obj).method(obj, *args, **kwargs). str.lower с право трябва да се нарича функция, защото нито един от нейните аргументи не е обвързан, докато obj.lower е метод, защото obj е обвързан като първи аргумент. - person BallpointBen; 05.09.2018

Използването на lower в type е добър начин да направите това, ако нямате нищо против да загубите информацията за случая.

Ако искате да запазите случая, можете да дефинирате персонализиран 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}
person hpaulj    schedule 23.12.2014
comment
Само за по-сигурно, вероятно бих направил choices = mylist(map(str.lower, ['win64', 'win32'])) или бих заменил __init__, за да направя това. - person BallpointBen; 05.09.2018

Запазването на информацията за случая също би било възможно с един ред:

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

Където изборите ще бъдат същият списък, който е предаден на параметъра за избор.

person Andreas Walter    schedule 31.10.2018