首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在使用带有a解析的自定义类型时出现常规参数错误

在使用带有a解析的自定义类型时出现常规参数错误
EN

Stack Overflow用户
提问于 2012-04-24 12:38:01
回答 3查看 3K关注 0票数 2

我需要基于给定的字符串创建自定义对象的实例(下面的示例中是Bar)。如果我,将类型更改为Bar并运行以下代码:

代码语言:javascript
运行
复制
import argparse

VALID_BAR_NAMES = ['alfa', 'beta', 'gamma', 'delta']


class Bar:

    def __init__(self, name):
        if not name in VALID_BAR_NAMES:
            raise RuntimeError('Bar can not be {n}, '
                               'it must be one of {m}'.format(
                                    n=name, m=', '.join(VALID_BAR_NAMES)))
        self.name = name


if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    parser.add_argument('foo', help='Specify the foo!')

    parser.add_argument('-b', '--bar', nargs='*',
                        choices=VALID_BAR_NAMES,
                        type=str,  # SELECTED TYPE
                        help=('Specify one or many valid bar(s)'))
    parsed_arguments = parser.parse_args()

当将无效的增强hello传递给-b时,我得到了相当好的输出。

代码语言:javascript
运行
复制
usage: Example.py [-h]
                  [-b [{alfa,beta,gamma,delta} [{alfa,beta,gamma,delta} ...]]]
                  foo
Example.py: error: argument -b/--bar: invalid choice: 'hello' (choose from 'alfa', 'beta', 'gamma', 'delta')

但是,如果我将type=str更改为type=Bar并再次运行该示例,则会得到以下输出:

代码语言:javascript
运行
复制
Traceback (most recent call last):
  File "C:\PyTest\Example.py", line 25, in <module>
    parsed_arguments = parser.parse_args()
  File "C:\Python27\lib\argparse.py", line 1688, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "C:\Python27\lib\argparse.py", line 1720, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "C:\Python27\lib\argparse.py", line 1926, in _parse_known_args
    start_index = consume_optional(start_index)
  File "C:\Python27\lib\argparse.py", line 1866, in consume_optional
    take_action(action, args, option_string)
  File "C:\Python27\lib\argparse.py", line 1778, in take_action
    argument_values = self._get_values(action, argument_strings)
  File "C:\Python27\lib\argparse.py", line 2218, in _get_values
    value = [self._get_value(action, v) for v in arg_strings]
  File "C:\Python27\lib\argparse.py", line 2233, in _get_value
    result = type_func(arg_string)
  File "C:\PyTest\Example.py", line 12, in __init__
    n=name, m=', '.join(VALID_BAR_NAMES)))
RuntimeError: Bar can not be hello, it must be one of alfa, beta, gamma, delta

看上去很糟糕。据我所知,这是由于类型转换发生之前,检查可用的选择是完成。处理这件事最好的方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-24 13:11:14

您需要创建一个自定义操作(未经测试):

代码语言:javascript
运行
复制
class Bar: 
    ...


class BarAction(argparse.Action):
    def __call__(self,parser,namespace,values,option_string=None):
        try:  #Catch the runtime error if it occures.
           l=[Bar(v) for v in values] #Create Bars, raise RuntimeError if bad arg passed.
        except RuntimeError as E:
           #Optional:  Print some other error here.  for example: `print E; exit(1)`  
           parser.error()

        setattr(namespace,self.dest,l) #add the list to the namespace

...
parser.add_argument('-b', '--bar', nargs='*',
                    choices=VALID_BAR_NAMES,
                    action=BarAction,  # SELECTED TYPE -- The action does all the type conversion instead of the type keyword.
                    help=('Specify one or many valid bar(s)'))

...
票数 2
EN

Stack Overflow用户

发布于 2012-04-24 12:40:23

将参数保持为字符串,直到解析完成为止。解析完成后,首先将它们转换为域对象。

票数 1
EN

Stack Overflow用户

发布于 2014-06-16 10:38:02

不知道它是否有用,但我将argparse.FileType作为参考:

代码语言:javascript
运行
复制
class Bar:
    def __call__(self, strting):
        if not name in VALID_BAR_NAMES:
            raise argparse.ArgumentError(None,'Bar can not be {n}, '
                               'it must be one of {m}'.format(
                                    n=name, m=', '.join(VALID_BAR_NAMES)))
        self.name = string

    def __init__(self):
        pass

    def __repr__(self):
        return name

parser.add_argument('-b', '--bar', nargs='*',
                    choices=VALID_BAR_NAMES,
                    type=Bar(),  # SELECTED TYPE
                    help=('Specify one or many valid bar(s)'))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10297973

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档