2010-09-23 12 views
5

Come posso passare un dizionario a uno script python da un altro script python tramite la riga di comando? Uso il sottoprocesso per chiamare il secondo script.Passare i dizionari a uno script Python tramite la riga di comando

Le opzioni che ho trovato sono:
I) Creare un modulo per analizzare un dizionario da una stringa (più approfondito di quanto speravo di andare).
II) Utilizzare un file temporaneo per scrivere un pickle e passare il nome del file come argomento
III) Non consentire dizionari, ma gestire coppie chiave/valore (ovvero "prog.py keya valuea keyb valub")

La soluzione non deve essere facile da usare, ma deve essere programmabile. Il secondo programma deve essere eseguito come processo separato, a causa di problemi di sicurezza e risorse.

risposta

6

parte pickle, un'altra opzione è ast.literal_eval, se i dizionari contengono solo primitive Python.

>>> d = {3: 9, 'apple': 'orange'} 
>>> s = str(d) 
>>> s 
"{3: 9, 'apple': 'orange'}" 
>>> import ast 
>>> x = ast.literal_eval(s) 
>>> x 
{3: 9, 'apple': 'orange'} 
+0

Questo era esattamente quello che stavo cercando –

6

Se non si ha bisogno di una struttura dati troppo complicata, potrei raccomandare simplejson? È disponibile come modulo integrato (chiamato json) in Python 2.6 e versioni successive.

+0

Sì, è possibile passare il dizionario serializzato JSON scrivendo al stdin del secondo script. – Epeli

+0

+1 perché JSON è semplice, efficace e quasi identico alla struttura 'dict' di Python. – jathanism

+0

+1 perché questo è perfetto, anche se la risposta di FoggleBird è perfetta, e non posso parlare con il capo in qualcosa che si occupa di javascript –

8

Hai guardato il modulo pickle per passare i dati su stdout/stdin?

Esempio:

knights.py:

import pickle 
import sys 

desires = {'say': 'ni', 'obtain': 'shrubbery'} 
pickle.dump(desires, sys.stdout) 

roundtable.py:

import pickle 
import sys 

knightsRequest = pickle.load(sys.stdin) 
for req in knightsRequest: 
    print "The knights %s %s." % (req, knightsRequest[req]) 

Uso e uscita:

$ python knights.py | python roundtable.py 
The knights say ni. 
The knights obtain shrubbery. 
+0

Non è una cattiva idea! – jathanism

0

Basta stampare il dizionario in uno script python

print("dict=" + str(dict)) 

e usarlo come

(python script1.py; cat script2.py) | python - 

e ora si dovrebbe essere in grado di accedere al dizionario attraverso variabile globale 'dict' nel secondo script python.

2

Se ciò che è nel dizionario (sia chiavi che valori) può essere rappresentato come stringhe, dovresti essere in grado di passarlo come argomento stringa al secondo script che può ricrearlo.

d = {'a':1,'b':2} 

d == eval(repr(d), None) 

>>>True 

Edit: Ecco un esempio un po 'più coinvolti mostrando il suo utilizzo con una semplice classe personalizzata:

class MyClass: 
    def __init__(self, a, b): 
     self.a = a 
     self.b = b 
    def __repr__(self): 
     return 'MyClass(%r, %r)' % (self.a, self.b) 
    def __eq__(self, other): 
     return (self.a == other.a) and (self.b == other.b) 

d = {'foo':42, 'bar': MyClass(17,'astring') } 

print 'd:', d 
print 'repr(d):', repr(d) 
print "d == eval(repr(d), {'MyClass':MyClass})?:", \ 
     d == eval(repr(d), {'MyClass':MyClass}) 

# outputs: 
# d: {'foo': 42, 'bar': MyClass(17, 'astring')} 
# repr(d): {'foo': 42, 'bar': MyClass(17, 'astring')} 
# d == eval(repr(d), {'MyClass':MyClass})?: True 
+0

'ast.literal_eval' è il modo sicuro e corretto per farlo. – FogleBird

+0

'ast.literal_eval()' può essere troppo restrittivo. Invece di None, è possibile passare a 'eval()' un secondo argomento che è invece un dizionario che associa i nomi di classi personalizzate alle corrispondenti classi personalizzate che, se fornite, consentirebbero di ricostituire anche le istanze di esse in aggiunta alle stringhe, numeri , tuple, liste, dict, booleani e nessun tipo di valore che 'ast.literal_eval()' supporta. – martineau

Problemi correlati