2014-04-17 24 views
5

Ho un sacco di script Python che usano codice comune per leggere input e scrivere file di output di tipi diversi.Modulo Python ArgParse: modifica il valore dell'argomento predefinito per argomento ereditato

Questi sono file di struttura chimica. Alcuni tipi di file di esempio potrebbero essere .smi o .sdf.

Per impostazione predefinita, desidero che alcuni di questi script forniscano dati nel formato di file "smi" e altri per l'output di dati nel formato "sdf".

È possibile sovrascrivere il valore predefinito di un argomento ereditato da un parser padre?

Per esempio ...

# Inherited code 
filesParser = argparse.ArgumentParser(add_help=False) 
filesParser.add_argument('-o', dest='outformat', default="smi") 

# Script code 
parser = argparse.ArgumentParser(description='inherts from filesParser', parents=[filesParser]) 
parser.add_argument('--foo') 

# Something like... 
# parser.outformat.default = "sdf" 

args = parser.parse_args() 

primo post in modo spero che la mia etichetta è OK.

Molte grazie, Dave

risposta

5

Sì (docs):

>>> parser.parse_args([]) 
Namespace(foo=None, outformat='smi') 
>>> parser.set_defaults(outformat='sdf') 
>>> parser.parse_args([]) 
Namespace(foo=None, outformat='sdf') 
+0

Grazie mille! Mi sono guardato intorno per un po 'e non l'ho notato. – user3544841

2

set_defaults è probabilmente la soluzione più semplice.

ma penso che la pena di sapere che è possibile modificare l'impostazione predefinita di un'azione direttamente

filesParser = argparse.ArgumentParser(add_help=False) 
outaction=filesParser.add_argument('-o', dest='outformat', default="smi") 
parser = argparse.ArgumentParser(description='inherts from filesParser', parents=[filesParser]) 
fooaction=parser.add_argument('--foo') 
print fooaction.default 
# None 
print outaction.default 
# 'smi' 
outaction.default='sdf' 
args=parser.parse_args() 
print args 
# Namespace(foo=None, outformat='sdf') 

add_argument restituisce un oggetto Action, che contiene tutte le informazioni che si è specificato negli argomenti. Qui salvo (collega a) quelle azioni nelle variabili outaction e fooaction. outaction.default è il valore predefinito utilizzato da parse_args.

Con il codice ereditato è probabilmente scomodo salvare il collegamento outaction (sebbene sia possibile trovarlo nell'elenco 'parser._actions'). Quindi ha senso lasciare che lo set_defaults faccia il lavoro per te.

Il codice per set_defaults può essere istruttivo:

def set_defaults(self, **kwargs): 
    self._defaults.update(kwargs) 

    # if these defaults match any existing arguments, replace 
    # the previous default on the object with the new one 
    for action in self._actions: 
     if action.dest in kwargs: 
      action.default = kwargs[action.dest] 

In primo luogo si mette i nuovi valori predefiniti nel dizionario parser._defaults, e poi si modifica in modo condizionale l'attributo action.default (notare la ricerca di parser._actions). Deve fare entrambe le cose, perché quando arriva il momento di utilizzare i valori predefiniti, il valore action.default ha la priorità sul valore parser._defaults.

Questi dettagli avranno più senso se si esegue questo codice in una shell interattiva (ad esempio Ipython) e si possono stampare gli oggetti action e parser. Si applicano le solite precauzioni su come giocare con attributi 'privati'.