2017-01-19 12 views
7

mam następujący program Pythona:Python argparse: Rodzaj niespójności podczas łączenia 'wybory', 'nargs' i 'default'

#!/usr/bin/env python 

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('arg', choices=['foo', 'bar', 'baz'], default='foo', nargs='*') 

args = parser.parse_args() 

print(args) 

Gdybym wywołać program tak:

./prog.py 

wyjście jest

Namespace(arg='foo') 

Ale jeśli wywołać program z foo jako argument:

./prog.py foo 

wyjście jest

Namespace(arg=['foo']) 

Pytanie

Jak mogę uzyskać arg „s wartość domyślną, aby stać się list?

Próbowałem

Próbowałem ustawienie default=['foo'] ale skutkuje:

prog.py: error: argument arg: invalid choice: ['foo'] (choose from 'foo', 'bar', 'baz') 
+1

Ten "duplikat" dotyczy akcji 'append'; jest to domyślny plik 'store' jeden. Mogę to ponownie otworzyć. – hpaulj

+0

Duplikat, który odrzuciłem: http://stackoverflow.com/questions/8526675/python-argparse-optional-append-argument-with-choices – hpaulj

Odpowiedz

3

To jest duplikatem stary, ale otwarte, bug/problem

http://bugs.python.org/issue9625 (argparse: Problem with defaults for variable nargs when using choices)

A positional z * otrzymuje specjalną obsługę. Jego wartość domyślna zawsze przechodzi przez test choices, jeśli nie podajesz wartości.

Porównaj to z przypadku optional

In [138]: p=argparse.ArgumentParser() 
In [139]: a=p.add_argument('--arg',choices=['foo','bar','baz'],nargs='*') 

In [140]: p.parse_args([]) 
Out[140]: Namespace(arg=None) 
In [141]: a.default=['foo'] 
In [142]: p.parse_args([]) 
Out[142]: Namespace(arg=['foo']) 

Domyślnym jest akceptowana bez badań:

In [143]: a.default=['xxx'] 
In [144]: p.parse_args([]) 
Out[144]: Namespace(arg=['xxx']) 

Odpowiedni kod jest:

def _get_values(self, action, arg_strings): 
    ... 
    # when nargs='*' on a positional, if there were no command-line 
    # args, use the default if it is anything other than None 
    elif (not arg_strings and action.nargs == ZERO_OR_MORE and 
      not action.option_strings): 
     if action.default is not None: 
      value = action.default 
     else: 
      value = arg_strings 
     self._check_value(action, value) 

Proponowana bug/problem patch dokonuje niewielkiej zmiany w tym bloku kodu.

+0

Wow, dziękuję za tak wiele myśli, nawet po zamknięciu go jako duplikować. Zamknęłbym to i zapomniałem o tym. +1 dla wysokiej jakości moderacji/odpowiedzi! :-) – anorm

Powiązane problemy