2013-01-02 22 views
83

Başlık hemen hemen gerçekleşmesini olsun isterim özetliyor. İşte , izin sadece pozitif tamsayılar

ben ne var ve program pozitif olmayan tamsayı üzerinde patlatmasa ederken, ben kullanıcı pozitif olmayan tamsayı temelde saçma olduğunu haberdar olmak istiyorum.

import argparse 
parser = argparse.ArgumentParser() 
parser.add_argument("-g", "--games", type=int, default=162, 
        help="The number of games to simulate") 
args = parser.parse_args() 

Ve çıkışı: negatif olan

python simulate_many.py -g 20 
Setting up... 
Playing games... 
.................... 

Çıktı: Şimdi

python simulate_many.py -g -2 
Setting up... 
Playing games... 

, belli ki if args.games negatif olduğunu belirlemek için eğer ben sadece bir ekleme olabilir, ama eğer merak ediyordum otomatik kullanım baskı yararlanmak üzere argparse seviyesinde tuzak bunu bir yolu vardı. şimdi ben yapıyorum için

python simulate_many.py -g -2 
usage: simulate_many.py [-h] [-g GAMES] [-d] [-l LEAGUE] 
simulate_many.py: error: argument -g/--games: invalid positive int value: '-2' 

ve ben mutlu değilim sanırım:

python simulate_many.py -g a 
usage: simulate_many.py [-h] [-g GAMES] [-d] [-l LEAGUE] 
simulate_many.py: error: argument -g/--games: invalid int value: 'a' 

böylece gibi:

İdeal olarak, bu buna benzer bir şey basacaktır

if args.games <= 0: 
    parser.print_help() 
    print "-g/--games: must be positive." 
    sys.exit(1) 

cevap

120

Bu type kullanan mümkün olmalıdır. Hala sizin için bu karar gerçek bir yöntem tanımlamak gerekir:

def check_positive(value): 
    ivalue = int(value) 
    if ivalue <= 0: 
     raise argparse.ArgumentTypeError("%s is an invalid positive int value" % value) 
    return ivalue 

parser = argparse.ArgumentParser(...) 
parser.add_argument('foo', type=check_positive) 

Bu temelde argparse tarihinde docs yılında perfect_square fonksiyonu sadece bir uyarlanmıştır örnektir. Eğer arg için min yanı sıra öngörülebilir max varsa

+1

sizin işlevi birden çok değer olabilir mi? Bu nasıl çalışıyor? – Tom

+0

Eğer 'int' dönüşümü başarısız olursa, hala okunabilir bir çıktı olacak mı? Yoksa bunun için el ile dönüşümü yükseltmeyi denemelisiniz? – NOhs

+2

@MrZ Bu, hata: argüman foo: geçersiz check_positive değeri gibi bir şey verir: 'foo = ' '. Daha iyi bir hata mesajı ile bir istisnayı yeniden gündeme getiren bir 'try: '...' dışında ValueError hariç. – Yuushi

3

hızlı ve kirli yolu, gibi, koşullar/çekler işlemek için önerilen seçenektir olacak bir aralıkta

parser.add_argument('foo', type=int, choices=xrange(0, 1000)) 
+12

Aşağı doğru, çirkin çıktı var. – jgritty

+3

_dirty_ üzerinde vurgu, sanırım. –

+2

jgritty'nin noktası hakkında daha net olmak için, seçenekler = xrange (0,1000), --help'ini kullandığınızda veya geçersiz bir argüman sağlandığında, 1 - 999 dahil olmak üzere tam sayılar listesinin tamamı için konsolunuza yazılır. Çoğu durumda iyi bir seçim değil. – biomiker

36

type ile choices kullanmaktır Yuushi'nin cevabında. Üst sınır biliniyorsa

özel durumda

, ayrıca choices parametre kullanabilir:

parser.add_argument('foo', type=int, choices=xrange(5, 10)) 
+2

Bunun bir verim yaratacağından ve bunun üzerinden bisiklet sürdüğünüzden, girişinizi doğrulayacağınızdan dolayı, bunun oldukça verimsiz olacağını düşünün. Hızlı bir "if" daha hızlıdır. – TravisThomas

+2

@ trav1th Gerçekten de olabilir, ancak bu dokümanlardan örnek bir kullanımdır. Ayrıca, cevabımda Yuushi'nin cevabının gideceği yanıt olduğunu söyledim. Seçenekleri vermek güzel. Ve argparse durumunda, yürütme başına bir kez oluyor, bir jeneratör ('xrange') kullanıyor ve ek kod gerektirmiyor. Bu ticaret müsait. Gidilecek yola karar vermek için her birine kadar. – aneroid

+9

Yazarın cevabının jgritty'in amacı hakkında daha net bir fikir sahibi olmak için, seçenekler = xrange (0,1000), kullanacağınız her defasında 1 - 999 dahil olmak üzere tam sayılar listesinin tamamı ile sonuçlanır. sağlanır. Çoğu durumda iyi bir seçim değil. – biomiker

2

daha basit bir alternatif, argparse.ArgumentParser sınıflara, parse_args yöntem içinde gelen doğrulama başlatmak için, özellikle . Bu teknik, özel bir çağrılabilir kadar havalı olmayabilir

def parse_args(self, args=None, namespace=None): 
    """Parse and validate args.""" 
    namespace = super().parse_args(args, namespace) # super() works in Python 3 
    if namespace.games <= 0: 
     raise self.error('The number of games must be a positive integer.') 
    return namespace 

, ama iş yok:

böyle bir alt sınıf içi

.


Hakkında ArgumentParser.error(message):

This method prints a usage message including the message to the standard error and terminates the program with a status code of 2.


Kredi: answer by jonatan

İlgili konular