Ho il seguente codice per creare un contenitore che finge di comportarsi come l'insieme di tutti i numeri primi (in realtà nasconde un test di primo memoised forza bruta)Python argparse scelte da un insieme infinito
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]
Che sembra di lavorare fino ad ora:
>>> primes = Primes()
>>> 7 in primes
True
>>> 104729 in primes
True
>>> 100 in primes
False
>>> 100 not in primes
True
Ma non sta giocando bene con 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
Il docs solo dire che
Qualsiasi oggetto che supporta l'operatore in può essere passato come le scelte valore, oggetti in modo dict, oggetti set, contenitori personalizzati, ecc sono tutti supportati.
Ovviamente non voglio ripetere l'infinito "set" di numeri primi. Quindi perché diavolo è argparse
provare a map
i miei numeri primi? Non ha solo bisogno di in
e not in
?
Grazie, ho creato un problema come suggerito [qui] (http://bugs.python.org/issue16697). – wim