2012-03-29 9 views
8

Z optparse, czy istnieje prosty sposób definiowania opcji negatywnych, np. --no-cleanup?Ujemne opcje boolowskie --no - cokolwiek w optparse?

zrobiłem to w ten sposób, ale jest to uciążliwe i bug-podatne, zwłaszcza ze względu na czeku None który jest łatwo zapomnieć i pozostawić na zewnątrz:

#!/bin/env python 

from __future__ import print_function 
import sys 
import optparse 

def main(argv): 
    parser = optparse.OptionParser("usage: %prog [options]") 
    parser.add_option("--no-cleanup", 
         dest = "cleanup", 
         action = "store_false", 
         help = "do cleanup at end?") 

    (opts, args) = parser.parse_args() 

    if opts.cleanup == None: 
     opts.cleanup = True 

    # do stuff ... 

    if opts.cleanup: 
     print("Cleaning up!", file = sys.stderr) 
    else: 
     print("Not cleaning up", file = sys.stderr) 

if __name__ == "__main__": 
    main(sys.argv[1:]) 

Idealnie chciałabym zrobić coś takiego Getoptions::Long w Perlu, gdzie mogę zdefiniować opcję cleanup jako wartość logiczną, a następnie automatycznie dostarczy ona --cleanup i --no-cleanup i odpowiednio ustawi moją zmienną logiczną.

+1

argparse ma tę funkcjonalność - czy nie jest to opcja? – jterrace

+0

@jterrace: Używam Pythona v2.6, więc myślę, że nie mam argparse. – Frank

+3

@Frank, argparse działa na python2.6, po prostu nie jest w standardowej bibliotece. Jeśli masz setuptools, 'easy_install argparse' zawsze działa dobrze dla mnie. – mgilson

Odpowiedz

4

Gdybym miał to zrobić, używając optparse (lub argparse o to chodziło - zakładając, że chcesz dodać flagę --cleanup i --no-cleanup w jednym poleceniu), po prostu podklasowałbym klasę parserów opcji. .. Coś jak:

from optparse import OptionParser 
class MyOptParse(OptionParser): 
     def boolean(self,dest,**kwargs): 
      self.add_option('--%s'%dest,dest=dest,action='store_true',**kwargs) 
      self.add_option('--no-%s'%dest,dest=dest,action='store_false',**kwargs) 

oczywiście, jest to kompletna hack, ale myślę, że to dość oczywiste, dokąd idę z nim ... można zrobić logiczną zachowywać jednak chcesz go (pomoc formatowania , akceptując wartość domyślną, tak aby albo "--blah", albo "--no-blah" było ustawione jako domyślne, itp.)

Myślę, że

parser=MyOptParse() 
parser.boolean('cleanup',default=True,help="Do/Do Not do cleanup") 

powinien działać i pozbyć się linii if options.cleanup is None natomiast to na niego, gdyż jest domyślnie ustawiony, chociaż komunikat pomoc będzie powtórzony (z kodem I dostarczony)

Jeśli chcesz po prostu dodać domyślne dla danej flagi (aby pozbyć się czekiem na None), można użyć domyślnego słowa kluczowego do add_option, OR, zgodnie z dokumentacją optparse ...

jaśniejszy sposób określić wartości domyślne jest set_defaults() metoda OptionParser, która y W dowolnej chwili możesz zadzwonić pod numer parse_args(): np. parser.set_defaults(verbose=True)

+0

powinieneś dodać '.replace ('-', '_')' w argumencie 'dest'. Czy możliwe jest skondensowanie pomocy, aby uniknąć nadmiarowości, jak w 'man gcc'? –

-1

optparse jest przestarzała. Można to zrobić przy użyciu argparse grupę argumentów:

#!/usr/bin/env python 
import argparse 

def main(): 
    parser = argparse.ArgumentParser() 
    group = parser.add_mutually_exclusive_group() 
    group.add_argument('--cleanup', action='store_true') 
    group.add_argument('--no-cleanup', dest='cleanup', action='store_false') 
    args = parser.parse_args() 

    # do stuff ... 

    if args.cleanup: 
     print("Cleaning up!") 
    else: 
     print("Not cleaning up") 

if __name__ == "__main__": 
    main() 

Zastosowanie grupy argumentów uniemożliwia określenie zarówno --cleanup i --no-cleanup. Jeśli nie zostanie podana żadna flaga, args.cleanup będzie None. Jeśli chcesz zmienić to na True lub False po prostu dodaj słowo kluczowe default o wymaganej wartości, dodając argument --cleanup do wykluczającej się grupy.

Dla użytkowników Python 2.6, możesz pip install argparse.

+2

To jednak nie powoduje automatycznego dodania flagi "--enable_cleanup". Chociaż jest to domyślna akcja, pomyślałem, że pytanie wymaga obecności obu flag ... – mgilson

+0

Naprawiono @mgilson. – wim

Powiązane problemy