Domanda

Faccio di programmazione scientifica, e spesso vogliono mostrare il prompt degli utenti e variabile di coppie, farli modificare le variabili, e poi fare il calulations con le nuove variabili.Lo faccio così spesso che ho scritto un wxPython classe di spostare questo codice del programma principale.È istituito un elenco per ciascuna variabile con il tipo della variabile (string, float, int), il prompt, e il valore corrente della variabile.Si poi posto tutte queste liste in un elenco di grandi dimensioni, e la mia utilità crea un ben formattato wxPython pannello con i prompt e i valori di corrente che può essere modificato.

Quando ho iniziato, ho avuto solo un paio di variabili, quindi mi sento di scrivere ogni variabile.

s='this is a string'; i=1; f=3.14
my_list=[ ['s','your string here',s], ['i','your int here',i], ['f','your float here'],]
input_panel = Input(my_list)

 # the rest of the window is created, the input_panel is added to the window, the user is
 # allowed to make  choices, and control returns when the user hits the calculate button

s,i,f = input_panel.results()     # the .results() function returns the values in a list

Ora voglio utilizzare questa routine per un sacco di variabili (10-30), e questo approccio si sta rompendo.Posso creare la lista di input per la funzione su più righe utilizzando l'elenco.append() dichiarazioni.Quando il codice restituito dalla funzione, però, ho questa lista enorme che deve essere scompattato nella giusta variabili.Questo è difficile da gestire, e sembra che non sarà facile ottenere la lista di input e di output elenco di sincronizzazione.E peggio ancora, sembra difettose.

Qual è il modo migliore per passare un sacco di variabili di una funzione in Python con informazioni aggiuntive, in modo che essi possono essere modificati, e quindi ottenere le variabili in modo che posso usare nel resto del programma?

Se potessi passare le variabili per riferimento, la funzione, gli utenti possono modificare o meno, e vorrei utilizzare i valori di una volta che il programma ha restituito dalla funzione.Ho solo bisogno di costruire la lista di input su più righe, e non ci sarebbe alcuna possibilità di ingresso in lista sempre fuori sincrono con la lista di output.Ma Python non lo permettono.

Devo rompere il grande elenchi di elenchi più piccoli che poi vengono combinati in grandi liste per il passaggio interno e al di fuori delle funzioni?O questo basta aggiungere più posti a fare errori?

È stato utile?

Soluzione

La cosa più semplice da fare sarebbe quella di creare una classe. Invece di trattare con un elenco di variabili, la classe avrà gli attributi. Poi è sufficiente utilizzare una singola istanza della classe.

Altri suggerimenti

Ci sono due opzioni decenti che vengono in mente.

Il primo è quello di utilizzare un dizionario per raccogliere tutte le variabili in un unico luogo:

d = {}
d['var1'] = [1,2,3]
d['var2'] = 'asdf'
foo(d)

La seconda è quella di utilizzare una classe per raggruppare tutti gli argomenti. Questo potrebbe essere qualcosa di semplice come:

class Foo(object):
    pass
f = Foo()
f.var1 = [1,2,3]
f.var2 = 'asdf'
foo(f)

In questo caso io preferirei la classe sopra il dizionario, semplicemente perché si potrebbe eventualmente fornire una definizione per la classe per rendere il suo utilizzo più chiara o per fornire metodi che gestiscono alcuni dei imballaggio e disimballaggio di lavoro.

Per me, la soluzione ideale è quella di utilizzare una classe come questa:

>>> class Vars(object):
...     def __init__(self, **argd):
...             self.__dict__.update(argd)
...
>>> x = Vars(x=1, y=2)
>>> x.x
1
>>> x.y
2

È inoltre possibile creare un dizionario e passare in questo modo:

>>> some_dict = {'x' : 1, 'y' : 2}
>>> #the two stars below mean to pass the dict as keyword arguments
>>> x = Vars(**some_dict)  
>>> x.x
1
>>> x.y
2

Si può quindi ottenere i dati o modificare come di necessità quando si passa ad una funzione:

>>> def foo(some_vars):
...     some_vars.z = 3 #note that we're creating the member z
...
>>> foo(x)
>>> x.z
3
  

Se potessi passare le variabili per riferimento nella funzione, gli utenti potrebbero cambiare o no, e vorrei utilizzare i valori una volta che il programma restituito dalla funzione.

È possibile ottenere lo stesso effetto come "passaggio per riferimento" passando un dict (o per convenienza sintattica un Bunch, vedere http://code.activestate.com/recipes/52308/ ).

se si dispone di un insieme finito di questi casi, si potrebbe scrivere funzioni specifiche wrapper per ciascuno di essi. Ogni involucro farebbe il lavoro di costruzione e disfare liste taht vengono passati alla funzione interna.

  1. Vorrei raccomandare l'uso di un dizionario o di una classe di accumulare tutti i dettagli circa le variabili
    • valore
    • il testo del prompt
  2. Una lista per memorizzare l'ordine in cui si desidera loro di essere visualizzati
  3. Quindi utilizzare il buon vecchio iterazione per preparare ingresso e raccogliere uscita

In questo modo sarà solo la modifica di un piccolo gestibile sezione del codice di volta in volta.Naturalmente, si dovrebbe riassumere tutto questo in una classe se proprio agio a lavorare con le classi.

"""Store all variables
"""
vars = {}
"""Store the order of display
"""
order = []

"""Define a function that will store details and order of the variable definitions
"""
def makeVar(parent, order, name, value, prompt):
    parent[name] = dict(zip(('value', 'prompt'), (value, prompt)))
    order.append(name)

"""Create your variable definitions in order
"""
makeVar(vars, order, 's', 'this is a string', 'your string here')
makeVar(vars, order, 'i', 1, 'your int here')
makeVar(vars, order, 'f', 3.14, 'your float here')

"""Use a list comprehension to prepare your input
"""
my_list = [[name, vars[name]['prompt'], vars[name]['value']] for name in order]
input_panel = Input(my_list)

out_list = input_panel.results();
"""Collect your output
"""
for i in range(0, len(order)):
    vars[order[i]]['value'] = out_list[i];
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top