来自无限集的Python argparse选择 [英] Python argparse choices from an infinite set

查看:141
本文介绍了来自无限集的Python argparse选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码来创建一个假装行为像所有素数集一样的容器(实际上隐藏了一个记忆的强力素数测试)

I have the following code to create a container which pretends to behave like the set of all prime numbers (actually hides a memoised brute-force prime test)

import math

def is_prime(n):
    if n == 2 or n == 3:
        return True
    if n == 1 or n % 2 == 0:
        return False
    else:
        return all(n % i for i in xrange(3, int(1 + math.sqrt(n)), 2))


class Primes(object):

    def __init__(self):
        self.memo = {}

    def __contains__(self, n):
        if n not in self.memo:
            self.memo[n] = is_prime(n)
        return self.memo[n]

到目前为止似乎有效:

>>> primes = Primes()
>>> 7 in primes
True
>>> 104729 in primes
True
>>> 100 in primes
False
>>> 100 not in primes
True

但是它与的效果不佳argparse

>>> import argparse as ap
>>> parser = ap.ArgumentParser()
>>> parser.add_argument('prime', type=int, choices=primes, metavar='p')
_StoreAction(option_strings=[], dest='prime', nargs=None, const=None, default=None, type=<type 'int'>, choices=<__main__.Primes object at 0x7f4e21783f10>, help=None, metavar='p')
>>> parser.parse_args(['7'])
Namespace(prime=7)
>>> parser.parse_args(['11'])
Namespace(prime=11)
>>> parser.parse_args(['12'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/argparse.py", line 1688, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/lib/python2.7/argparse.py", line 1720, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/lib/python2.7/argparse.py", line 1929, in _parse_known_args
    stop_index = consume_positionals(start_index)
  File "/usr/lib/python2.7/argparse.py", line 1885, in consume_positionals
    take_action(action, args)
  File "/usr/lib/python2.7/argparse.py", line 1778, in take_action
    argument_values = self._get_values(action, argument_strings)
  File "/usr/lib/python2.7/argparse.py", line 2219, in _get_values
    self._check_value(action, value)
  File "/usr/lib/python2.7/argparse.py", line 2267, in _check_value
    tup = value, ', '.join(map(repr, action.choices))
TypeError: argument 2 to map() must support iteration

docs 只是说


任何支持in运算符的对象都可以作为选择
值传递,所以dict对象,set对象,自定义容器等。支持所有

Any object that supports the in operator can be passed as the choices value, so dict objects, set objects, custom containers, etc. are all supported.

显然我不想迭代质数的无限集合。那么为什么这个 argparse 试图 map 我的素数?是不是只需中的中的

Obviously I don't want to iterate the infinite "set" of primes. So why the heck is argparse trying to map my primes? Doesn't it just need in and not in?

推荐答案

这似乎是一个文档错误。编写的库要求选项参数不仅仅是一个容器而且是可迭代的,它试图列出可用的选项,这对你的情况不起作用。你可以尝试通过给它一个假的 __ iter __ 来破解它,只返回一些信息字符串。

It appears to be a documentation bug. The library as written requires the choices argument to be not just a container but also iterable, It tries to list the available options, which isn't going to work for your case. You could try to hack it by giving it a fake __iter__ that just returns some informational string.

你也可以想要将此提交为Python错误跟踪器中的错误,因为该行为确实与文档相矛盾。

You might also want to submit this as a bug in the Python bug tracker, since the behavior really is contradicted by the docs.

这篇关于来自无限集的Python argparse选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆