2010-07-06 4 views
1

J'ai un petit programme Python composé de très peu de modules (environ 4). Le module principal crée une liste de tuples, représentant ainsi un certain nombre d'enregistrements. Ces tuples sont disponibles pour les autres modules via une simple fonction qui les renvoie (par exemple, get_records()).Est-il correct d'échanger des tuples entre des modules Python?

Je ne suis pas sûr si c'est un bon design cependant. Le problème étant que les autres modules ont besoin de connaître les index de chaque élément du tuple. Cela augmente le couplage entre les modules, et n'est pas très transparent pour quelqu'un qui veut utiliser le module principal.

Je peux penser à deux alternatives:

  1. Faire les valeurs d'index des éléments de tuple disponibles comme des constantes de module (par exemple, IDX_RECORD_TITLE, IDX_RECORD_STARTDATE, etc.). Cela évite le besoin de nombres magiques comme title = record[3].

  2. N'utilisez pas de tuples, mais créez une classe d'enregistrement et renvoyez une liste de ces objets de classe. L'avantage étant que les méthodes de classe auront des noms auto-explicites comme record.get_title(). N'utilisez pas de tuples, mais plutôt des dictionnaires à la place. Donc, dans ce scénario, la fonction renvoie une liste de dictionnaires. L'avantage étant que les clés du dictionnaire sont également explicites (bien que quelqu'un utilisant le module aurait besoin de les connaître). Mais cela semble être un énorme frais généraux.

Je trouve tuples d'être l'une des grandes forces de Python (très facile à transmettre des données composées autour sans les frais généraux de codage des classes/objets), donc j'utiliser actuellement (1), mais toujours se demander ce qui être la meilleure approche.

Répondre

4

je ne vois pas de frais généraux ou la complexité des objets passant au-dessus uplets (tuples sont aussi des objets)

OMI si tuple sert votre but d'utiliser facilement, mais comme vous avez vu les contraintes juste passer à une classe qui représente vos données proprement

class MyData(object): 
    def __init__(self, title, desc): 
     self.title = title 
     self.desc = desc 

Vous n'avez pas besoin d'ajouter de méthode getter ou setter.

+0

Je pensais en effet à l'overhead des getters et setters, mais j'ai oublié qu'en Python ce n'est pas strictement nécessaire. – Rabarberski

0

Dans ces cas, j'ai tendance à utiliser des dictionnaires. Si seulement pour avoir des choses facilement compréhensibles pour moi-même quand je reviens un peu plus tard pour utiliser le code.

Je ne sais pas si c'est un "énorme frais généraux". Je suppose que cela dépend de combien de fois vous le faites et à quoi il sert. Je commence avec la solution la plus simple et optimise quand j'en ai vraiment besoin. J'ai rarement besoin de changer quelque chose comme ça.

+0

La surcharge serait dans les clés du dictionnaire étant présent dans chaque 'enregistrement'. Puisque le nombre d'enregistrements ne sera jamais important dans mon cas (<100), les frais généraux sont en effet négligeables, mais ils ne me paraissent pas «bons». – Rabarberski

+0

Je suis d'accord sur le sentiment. :) Je ne sais pas si je suis endommagé par la programmation C++/Java, mais pour une raison quelconque, il est préférable d'avoir une sorte de classe de données contenant les valeurs. Cela permet également à votre IDE avec l'achèvement du code dans certains cas. :) La suggestion 'namedtuple' de gnibbler semble cependant être un bon compromis. –

+1

Et la documentation 'namedtuple' dit explicitement: * Les instances de tuple nommées n'ont pas de dictionnaires par instance, elles sont donc légères et ne nécessitent pas plus de mémoire que les tuples standard. * – Rabarberski