Question

Je fais la programmation scientifique, et je souhaite souvent montrer aux utilisateurs des invites et des paires de variables, laissez-les modifier les variables, puis effectuez les calulations avec les nouvelles variables. Je le fais si souvent, que j'ai écrit une classe wxPython pour déplacer ce code sur le programme principal. Vous configurez une liste pour chaque variable selon le type de la variable (string, float, int), l'invite et la valeur actuelle de la variable. Vous placez alors toutes ces listes dans une grande liste, et mon utilitaire crée un panneau wxPython soigneusement avec des invites et formated les valeurs actuelles qui peuvent être modifiés.

Quand j'ai commencé, je n'avais quelques variables, donc j'écrire chaque variable.

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

Maintenant, je veux utiliser cette routine pour beaucoup de variables (10-30), et cette approche se délite. Je peux créer la liste d'entrée à la fonction sur plusieurs lignes en utilisant les états list.append (). Lorsque le code retour de la fonction, cependant, je reçois cette énorme liste qui doit être décompressé dans les bonnes variables. Ceci est difficile à gérer, et il semble que ce sera facile d'obtenir la liste d'entrée et de sortie liste de synchronisation. Et pire que cela, il semble kludgy.

Quelle est la meilleure façon de passer beaucoup de variables à une fonction en Python avec des informations supplémentaires afin qu'ils puissent être édités, puis obtenir les variables de retour afin que je puisse les utiliser dans le reste du programme?

Si je pouvais passer les variables par référence dans la fonction, les utilisateurs peuvent les changer ou non, et j'utiliser les valeurs une fois que le programme de retour de la fonction. Je seulement besoin de construire la liste des entrées sur plusieurs lignes, et il n'y aurait pas de possibilité de la liste d'entrée sortir de la synchronisation avec la liste de sortie. Mais Python ne permet pas.

Dois-je briser les grandes listes dans des listes plus petites qui se combinent ensuite dans de grandes listes pour passer dans et hors des fonctions? Ou est-ce juste ajouter d'autres endroits pour faire des erreurs?

Était-ce utile?

La solution

La chose la plus simple serait de créer une classe. Au lieu de faire face à une liste de variables, la classe des attributs. Ensuite, il suffit d'utiliser une seule instance de la classe.

Autres conseils

Il y a deux options décents qui viennent à l'esprit.

La première consiste à utiliser un dictionnaire pour rassembler toutes les variables en un seul endroit:

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

La seconde est d'utiliser une classe pour regrouper tous les arguments. Cela pourrait être quelque chose d'aussi simple que:

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

Dans ce cas, je préférerais la classe sur le dictionnaire, simplement parce que vous pourriez éventuellement fournir une définition de la classe pour rendre son utilisation plus claire ou de fournir des méthodes qui traitent une partie de l'emballage et le déballage travail.

Pour moi, la solution idéale est d'utiliser une classe comme ceci:

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

Vous pouvez également créer un dictionnaire et le transmettre comme ceci:

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

Vous pouvez alors obtenir des données ou modifier comme il y a lieu lors du passage à une fonction:

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

Si je pouvais passer les variables par référence dans la fonction, les utilisateurs peuvent les changer ou non, et j'utiliser les valeurs une fois que le programme de retour de la fonction.

Vous pouvez obtenir le même effet que « passer par référence » en passant un dict (ou pour la commodité syntaxique un Bunch, voir http://code.activestate.com/recipes/52308/ ).

si vous avez un ensemble fini de ces cas, vous pouvez écrire des fonctions wrapper spécifiques pour chacun d'eux. Chaque emballage ferait le travail de la construction et le déballage des listes sont transmises à taht la fonction interne.

  1. Je vous recommande d'utiliser un dictionnaire ou une classe d'accumuler tous les détails A propos de vos variables
    • valeur
    • texte invite
  2. Une liste pour stocker l'ordre dans lequel vous voulez à afficher
  3. Utilisez ensuite une bonne vieille itération pour préparer l'entrée et la sortie collecter

De cette façon, vous ne serez en train de modifier une petite section gérable du temps de code et encore. Bien sûr, vous devez résumer tout cela dans une classe si votre aise avec les classes.

"""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];
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top