来自无限集的Python argparse选择 [英] Python argparse choices from an infinite set
问题描述
我有以下代码来创建一个假装行为像所有素数集一样的容器(实际上隐藏了一个记忆的强力素数测试)
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屋!