Frage

ich wissenschaftliche Programmierung und wollen oft Benutzer Eingabeaufforderungen und Variablenpaare zeigen, lassen Sie sie die Variablen bearbeiten, und dann mit den neuen Variablen, die die Berechnungen am tun. Ich tue dies, so oft, dass ich eine WxPython Klasse schrieb aus dem Hauptprogramm diesen Code zu bewegen. Sie legen eine Liste für jede Variable mit dem Typ der Variablen (string, float, int), die Eingabeaufforderung, und der aktuelle Wert der Variablen. Sie dann alle diese Listen in einer großen Liste setzen und mein Dienstprogramm erstellt eine ordentlich formatiert WxPython Panel mit Eingabeaufforderungen und den aktuellen Werten, die bearbeitet werden können.

Als ich anfing, hatte ich nur ein paar Variablen, also würde ich jede Variable schreiben.

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

Jetzt möchte ich für viele Variablen diese Routine verwenden (10-30), und dieser Ansatz bricht zusammen. Ich kann die Eingabeliste an die Funktion über mehrere Zeilen erstellen die list.append mit () Aussagen. Wenn der Code aus der Funktion zurückgibt, obwohl ich diese riesige Liste erhalten, die in die richtigen Variablen ausgepackt werden muss. Das ist schwierig zu handhaben, und es sieht aus wie es einfach sein wird, die Eingabeliste und Ausgabeliste nicht synchron zu bekommen. Und was noch schlimmer als das, es sieht kludgy.

Was ist der beste Weg, viele Variablen an eine Funktion in Python mit zusätzlichen Informationen zu übergeben, so dass sie bearbeitet werden kann, und dann die Variablen zurück, so dass ich sie in dem Rest des Programms verwenden kann?

Wenn ich die Variablen durch Verweis in die Funktion übergeben kann, dann konnten Benutzer sie ändern oder nicht, und ich würde die Werte, sobald das Programm von der Funktion zurück verwenden. Ich würde nur die Eingangsliste über mehrere Zeilen zu bauen, und es gäbe keine Möglichkeit der Eingangsliste wird nicht synchron mit der Ausgabeliste zu bekommen. Aber Python nicht zulassen.

Soll ich die großen Listen in kleinere Listen brechen, die dann in große Listen kombiniert bekommen für die Weitergabe in die und aus der Funktionen? Oder ist dies nur mehr Plätze in den Fehler machen?

War es hilfreich?

Lösung

Die einfachste Sache zu tun wäre, um eine Klasse zu erstellen. Statt mit einer Liste von Variablen zu tun, werden die Klassenattribute haben. Dann nur eine einzelne Instanz der Klasse verwendet werden.

Andere Tipps

Es gibt zwei anständige Optionen, die in den Sinn kommen.

Der erste ist ein Wörterbuch verwenden, um alle Variablen an einem Ort zu sammeln:

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

Die zweite ist eine Klasse zu verwenden, um alle Argumente zu bündeln. Dies könnte etwas so einfach wie:

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

In diesem Fall würde ich die Klasse über das Wörterbuch es bevorzugt, nur weil Sie schließlich eine Definition für die Klasse ihrer Verwendung klarer bieten könnten zu machen oder Verfahren bereitzustellen, die einen Teil der Ein- und Auspacken Arbeit behandeln.

Für mich ist die ideale Lösung ist eine Klasse wie folgt zu verwenden:

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

Sie können auch ein Wörterbuch bauen und es so passieren:

>>> 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

Sie können dann Daten erhalten oder ändern, als es sein muss, wenn es an eine Funktion:

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

Wenn ich die Variablen durch Verweis in die Funktion übergeben könnte, dann könnte den Benutzer sie ändert oder nicht, und ich würde die Werte benutzen, wenn das Programm von der Funktion zurückgegeben.

Sie können den gleichen Effekt wie „durch Verweis übergeben“ erhalten, indem ein dict (oder für syntaktische Bequemlichkeit vorbei ein Bunch finden Sie unter http://code.activestate.com/recipes/52308/ ).

Wenn Sie eine endliche Menge dieser Fälle haben, könnten Sie bestimmte Wrapper-Funktionen für jeden schreiben. Jeder Wrapper würde die Arbeit des Gebäudes und Auspacken Listen taht auf die interne Funktion übergeben werden.

  1. Ich würde empfehlen, ein Wörterbuch mit oder eine Klasse alle Details zu akkumulieren über Ihre Variablen
    • Wert
    • Aufforderungstext
  2. Eine Liste zu speichern, die Reihenfolge, in der sie angezeigt werden sollen
  3. Dann gute alte Iteration verwendet Eingabe vorzubereiten und sammeln Ausgang

Auf diese Weise erhalten Sie nur einen kleinen überschaubaren Abschnitt des Codes immer wieder werden zu ändern. Natürlich sollte man all dies in einer Klasse kapseln, wenn Ihr wohl mit Klassen arbeiten.

"""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];
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top