6.20.5.2 Aggiungere nuove azioni

Aggiungere nuove azioni è un pò più complesso, perché dovete comprendere il fatto che optparse possiede una coppia di classificazioni per le azioni:

azioni ``store''
azioni che appaiono in optparse memorizzando un valore in un attributo dell'istanza OptionValues; queste opzioni richiedono un attributo dest da fornire nel costruttore Option
azioni ``typed''
azioni che prendono un valore da riga di comando, e si aspettano che sia di un certo tipo; o diversamente, una stringa che può venire convertita in un certo tipo. Queste opzioni richiedono un attributo di tipo (NdT: type) nel costruttore Option.

Alcune azioni predefinite ``store'' sono store, store_const, append e count. Le predefinite per l'azione ``typed'' sono store, append e callback.

Quando aggiungete un'azione, dovrete decidere se si tratta di una azione ``store'' o ``typed'', nessuna delle due, o entrambe. Tre attributi di Option (o di una sua classe derivata) controllano questo fatto:

ACTIONS
Tutte le azioni devono venire elencate come stringhe in ACTIONS.
STORE_ACTIONS
Le azioni ``store'' vengono aggiunte qui.
TYPED_ACTIONS
Le azioni ``typed'' vengono aggiunte qui.

Per poter implementare la vostra nuova azione, dovrete sovrascrivere il metodo take_action() di Option, e implementare un caso che riconosca la vostra azione.

Per esempio, aggiungete un'azione ``extend''. Questa è simile all'azione standard ``append'', ma invece di prendere un singolo valore dalla riga di comando e aggiungerlo alla lista esistente, ``extend'' prenderà valori multipli in una stringa delimitata da virgole, e quindi estenderà con essi una lista esistente. Così, se --names è un'opzione ``extend'' di tipo stringa, la riga di comando:

--names=foo,bar --names blah --names ding,dong

potrebbe risultare in un lista:

["foo", "bar", "blah", "ding", "dong"]

Definiamo ancora una classe derivata di Option:

class MyOption(Option):

    ACTIONS = Option.ACTIONS + ("extend",)
    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)

    def take_action(self, action, dest, opt, value, values, parser):
        if action == "extend":
            lvalue = value.split(",")
            values.ensure_value(dest, []).extend(lvalue)
        else:
            Option.take_action(
                self, action, dest, opt, value, values, parser)

Note aggiuntive:

Se l'attributo attr di values non esiste o vale None, per prima cosa ensure_value() lo imposta a value e quindi restituisce value. Questo è molto utile per azioni come ``extend'', ``append'' e ``count'', ciascuna delle quali accumula dati in una variabile, e si aspetta che la variabile sia di un certo tipo (una lista per le prime due, un intero per l'ultima). L'uso di ensure_value() indica che che gli script contenenti la vostra azione non si debbano preoccupare di impostare un valore predefinito per le destinazioni della opzione in questione; possono lasciare semplicemente il valore predefinito a None, e ensure_value() si prenderà cura di restituire il valore giusto quando richiesto.

Vedete Circa questo documento... per informazioni su modifiche e suggerimenti.