On 2013-05-18 09:26, Marco Beri wrote:
Il giorno 18/mag/2013 01:33, "Daniele Varrazzo" <p...@develer.com> ha
scritto:
Guarda optparse o argparse nella libreria python. Entrambi restituiscono
un oggetto che contiene tutti i parametri come attributi. Tipicamente
ottieni quello nel main() e poi passi l'oggetto o solo i valori che servono
a funzioni o oggetti create nel main.

Ad un talk a djangocon, non nella libreria standard, hanno segnalato questa
bella libreria standard:

https://github.com/docopt/docopt

"questa bella libreria", non standard.

La conosco. Gneh. Mah. Non mi ha fatto godere. La usa un mio collega: il giochino è che tutte le volte prova a ficcarla nei progetti dove lavoro anche io gliela rimuovo e la sostituisco con optparse o argparse.

Non amo forzare un messaggio pensato per il consumo umano ad assumere tutti i vincoli necessari perché un computer lo capisca. È la stessa critica che muovo a doctest. Bello come giochino ma a farci qualcosa di serio e mantenerlo la vedo pesa.

In particolare di solito devo mettere due opzioni in croce e per quello uso optparse. Un mio progetto (PGXN Client) ha una riga di comando di cui sorvolo i dettagli implementativi, ma restando nel semplice ogni subcommand è implementato da una classe che richiede certe opzioni: anche solo questo con docopt non si può fare, la CLI è "monolitica", non dinamica, e va generata in un solo punto.

Un pattern che invece uso molto sul lavoro, dove di script ne creo tanti, è quello che mi serve spesso una coppia --quiet/--verbose che vanno ad alterare il level di un logger, mi serve spesso una coppia --start-date/--end-date che restituiscono oggetti date (prendendo sia YYYY-MM-DD sia un numero di "giorni indietro" in modo da poter mettere in un crontab --start-date 7 --end-date 1 per elaborare l'ultima settimana), mi serve spesso un --dsn per settare il database dove lavorare. Usando docopt dovrei ripetere in continuazione sia l'impostazione della command line che il parsing delle opzioni ed eventualmente farci qualcosa (es. impostare il level del logger). Con optparse invece ho scritto delle funzioni che mi permettono di fare:

    def parse_cmdline():
        parser = optparse.OptionParser(usage=...)
        parser.add_option("--roba-specifica-per-lo-script"...)

        @script_utils.with_two_date(parser)
        @script_utils.with_verbosity(parser)
        @script_utils.with_dsn(parser)
        def parse():
            opt, args = parser.parse_args()
            opt.files = args # per esempio
            return opt

        return parse()

Perché coi decoratori? Per la "doppia azione": quando il decoratore viene applicato il parser viene popolato. Quando la funzione esce il decoratore ha accesso ad opt e può verificare la validità dei valori, o qualunque altra operazione (impostare una varabile globale...). Per esempio questa è una delle implementazioni:

    def with_verbosity(parser, logger_name=None):
        """Decorator to add --quiet and --verbose options to a script.

Takes an optional logger_name: if specified set the level on that logger,
        otherwise set it on the root logger.

Set the log level on WARNING if --quiet is specified, on DEBUG if --verbose is specified, on INFO if none is. Won't tell you what happens if
        you specify both: sod off, wise guy.
        """
        def with_verbosity_(f):
            @wraps(f)
            def with_verbosity__(*args, **kwargs):
parser.add_option('--quiet', dest='loglevel', default=logging.INFO,
                    action='store_const', const=logging.WARNING,
                    help="show less information")
parser.add_option('--verbose', dest='loglevel', default=logging.INFO,
                    action='store_const', const=logging.DEBUG,
                    help="show more information")

                opt = f(*args, **kwargs)

                logging.getLogger(logger_name).setLevel(opt.loglevel)

                return opt

            return with_verbosity__

        return with_verbosity_

Anche questo non si può fare con docopt: ad ogni script dovrei ripetere le stesse dichiarazioni e le stesse operazioni.


--
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com
_______________________________________________
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python

Reply via email to