8
votes

Noms de paramètres dans les fonctions Python qui prennent un seul objet ou itérable

J'ai des fonctions dans mon code qui acceptent un objet ou un iTable d'objets comme entrée. On m'a appris à utiliser des noms significatifs pour tout, mais je ne sais pas comment se conformer ici. Que devrais-je appeler un paramètre pouvant être un objet Sinlge ou un ierable d'objets? J'ai mangé deux idées, mais je n'aime pas l'un d'entre eux:

  1. fooormanyfoos - cela exprime ce qui se passe, mais je pouvais imaginer que quelqu'un n'était pas habitué à cela pourrait avoir du mal à comprendre ce que cela signifie tout de suite
  2. param - un nom générique. Cela précise que cela peut être plusieurs choses, mais n'explique rien de ce que le paramètre est utilisé pour.

    Normalement, j'appelle itérables d'objets juste le pluriel de ce que j'appellerais un seul objet. Je sais que cela pourrait sembler un peu compulsif, mais Python est censé être (entre autres) sur la lisibilité.


2 commentaires

Devez-vous accepter un seul objet, au lieu d'un iérien d'un objet? Cela rendrait votre code beaucoup plus clair (c'est-à-dire passer [foo] au lieu de foo ).


@Katrielaalex: C'est possible. J'ai un fond C ++ et je suis utilisé pour utiliser des surcharges pour ce type de problème. Peut-être que j'ai de repenser à faire ici.


9 Réponses :


-1
votes

Je travaille maintenant sur un projet assez gros maintenant et que nous passons des cartes autour et appelez simplement notre paramètre carte . Le contenu de la carte varie en fonction de la fonction qui est appelée. Ce n'est probablement pas la meilleure situation, mais nous réutilisons beaucoup de même code sur les cartes, il est donc plus facile de copier et de coller.

Je dirais au lieu de la nommer ce que c'est, vous devriez nommer ce qu'il est utilisé. Aussi, veillez simplement à ce que vous ne puissiez pas appeler utiliser dans sur un non fonctionnel.


3 commentaires

Carte Étant défini par Python lui-même, il s'agit d'un choix potentiellement déroutant en tant que nom de paramètre: les gens attendent cartographique pour signifier la carte de Python .


D'accord avec ce que @Eol a dit. C'est une bonne idée d'éviter d'utiliser des noms de fonctions intégrées en tant que noms de paramètres.


Je ne veux pas dire que je réutilise complètement le code par colle-coller. Comme je l'ai dit, ce n'est probablement pas la meilleure solution. Mon deuxième paragraphe était plus ma réponse.



0
votes

J'irais avec un nom expliquant que le paramètre peut être une instance ou une liste d'instances. Dites one_or_more_foo_Objects . Je le trouve mieux que le paramètre param .


0 commentaires

1
votes

Pouvez-vous nommer votre paramètre de très haut niveau? Les personnes qui achètent le code sont plus intéressées par la connaissance de ce que le paramètre représente ("clients") que ce que leur type est ("list_of_tuples"); Le type peut être défini dans la chaîne de documentation de fonction, qui est une bonne chose car cela pourrait changer, à l'avenir (le type est parfois un détail de mise en œuvre).


2 commentaires

Mon problème ici est que quelque chose comme Clients suggère plusieurs objets. Si un appelant veut uniquement passer un seul objet, il peut penser qu'il doit s'enrouler dans certains iéres (ce serait mon intuition). Je cherche un moyen d'exprimer cet objectif unique aussi.


@ Space_C0WB0Y: J'abandonnerais l'indique le type de paramètre dans le nom du paramètre et inclure ces informations tôt dans la chaîne de documentation. Après tout, vous avez souvent avoir d'appeler une liste comme file_lines même lorsque vous savez que cette liste ne peut contenir qu'une seule ligne. Personne ne s'attendra à que vous appelez cela file_line_or_file_lines . Donc, je suggérerais que votre code sera parfaitement lisible si vous utilisez un nom descriptif court et de haut niveau. :)



7
votes

J'ai quelques fonctions dans mon code qui acceptent un objet ou un itérable d'objets en entrée.

Ceci est une chose très exceptionnelle et souvent très mal à faire. Il est trivialement évitable.

i.e.., Passer [foo] au lieu de foo lorsque vous appelez cette fonction.

Le seul moment où vous pouvez justifier le faire est quand (1), vous disposez d'une base installée de logiciel qui attend une forme (ou itérables singleton) et (2), vous devez développer pour soutenir l'autre cas d'utilisation. Alors. Vous uniquement faire lors de l'expansion d'une fonction existante qui a une base de code existant.

Dans ce nouveau développement, ne le faites pas.

Je suis venu avec deux idées, mais je ne suis pas comme l'un d'eux:

[Seulement deux?]

FooOrManyFoos - Ce exprime ce qui se passe, mais je ne pouvais imaginer que quelqu'un n'a pas l'habitude pourrait avoir du mal à comprendre ce que cela signifie tout de suite

Quoi? Voulez-vous dire que vous fournissez PAS d'autres documents, et aucune autre formation? Pas de support? Aucun conseil? Qui est le « quelqu'un n'a pas l'habitude »? Parlez-leur. Ne présumez pas ou imaginer des choses à leur sujet.

En outre, ne pas utiliser avant supérieur noms de cas.

param - un nom générique. Cela montre clairement qu'il peut être plusieurs choses, mais ne rien expliquer sur ce que le paramètre est utilisé.

Terrible. Jamais. Faire. Cela.

J'ai regardé dans la bibliothèque Python pour des exemples. La plupart des fonctions qui font des descriptions simples.

http://docs.python.org/library/functions.html#isinstance < / a>

isinstance (objet, ClassInfo)

Ils l'appellent « ClassInfo » et il peut être une classe ou un tuple de classes.

Vous pouvez aussi le faire.

doit considérer le cas d'usage courant et les exceptions. Suivez la règle 80/20.

  1. 80% du temps, vous pouvez le remplacer par un itérables et ne pas avoir ce problème.

  2. Dans les 20% restants des cas, vous avez une base installée de logiciel construit autour d'une hypothèse (que ce soit de l'élément itérables ou simple) et vous devez ajouter l'autre cas. Ne changez pas le nom, il suffit de changer la documentation. Si elle avait coutume de dire « foo », il dit encore « foo » mais vous faire accepter une itérables de « Foo » sans aucune modification des paramètres. Si elle avait coutume de dire « foo_list » ou « foo_iter », il dit encore « foo_list » ou « foo_iter », mais il ne tolérera tranquillement un singleton sans se rompre.

    • 80% du code est l'héritage ( "toto" ou "foo_list")

    • 20% du code est la nouvelle fonction ( "toto" peut être un iterable ou "foo_list" peut être un seul objet.)


0 commentaires

3
votes

On dirait que vous êtes agonisant sur la laideur du code comme: xxx pré>

Ma suggestion est d'éviter de surcharger votre interface pour gérer deux cas distincts. J'ai tendance à écrire du code qui favorise la réutilisation et désigné de la nommage des méthodes sur une utilisation dynamique intelligente des paramètres: P>

def ProcessOneWidget(widget):
  #...

def ProcessManyWidgets(widgets):
  for widget in widgets:
    ProcessOneWidget(widget)


0 commentaires

2
votes

Vous pouvez utiliser * args magique (varargs) pour que vos paramètres soient toujours propres.

Passez un seul élément ou plusieurs éléments connus comme fonction normale arguments comme Func (arg1, arg2, ...) et transmettez des arguments itables avec un astérisque avant, comme Func (* args) strong> p>

Exemple: P>

# magic *args function
def foo(*args):
    print args

# many ways to call it
foo(1)
foo(1, 2, 3)

args1 = (1, 2, 3)
args2 = [1, 2, 3]
args3 = iter((1, 2, 3))

foo(*args1)
foo(*args2)
foo(*args3)


0 commentaires

1
votes

Je ferais 1 chose, xxx

alors vous n'avez plus besoin de vous inquiéter de son nom.

dans une fonction que vous devriez essayer d'atteindre Avoir 1 action, acceptez le même type de paramètre et renvoyez le même type.

au lieu de remplir les fonctions avec les IFS que vous pourriez avoir 2 fonctions.


0 commentaires

1
votes

Puisque vous ne vous souciez pas exactement de quel type de démonteur vous obtenez, vous pouvez essayer d'obtenir un itérateur pour le paramètre utilisant iter (). Si iTER () soulève une exception TypeError, le paramètre n'est pas démarré, de sorte que vous créez une liste ou un tuple de l'un de l'un, qui est iérêlé et de votre oncle de Bob. XXX

Le seul problème Avec cette approche, c'est si FOO est une chaîne. Une chaîne est démarrée, donc en passant dans une seule chaîne plutôt qu'une liste de chaînes entraînera une itération sur les caractères d'une chaîne. S'il s'agit d'une préoccupation, vous pouvez ajouter un test de test pour cela. À ce stade, il s'agit de Wordy pour le code de la chaudron, donc je le briserais dans sa propre fonction. xxx

Contrairement à certaines de ces répondeurs, j'aime faire cela, puisque ça Élimine une chose que l'appelant pourrait vous tromper lors de l'utilisation de votre API. "Sois conservateur dans ce que vous générez, mais libéral dans ce que vous acceptez."

Pour répondre à votre question initiale, c'est-à-dire ce que vous devez nommer le paramètre, je vais toujours avec "foos" même si vous acceptiez un Article unique, puisque votre intention est d'accepter une liste. Si ce n'est pas démarré, c'est techniquement une erreur, bien que vous corrigerez pour l'appelant depuis le traitement, le seul article est probablement ce qu'ils veulent. En outre, si l'appelant pense ils doivent réussir dans une iérêtant même d'un article, ce qui fonctionnera bien sûr bien et nécessite très peu de syntaxe, alors pourquoi vous inquiétez-vous de la correction de leur mauvaise compréhension?


0 commentaires

4
votes

Je suppose que je suis un peu tard à la fête, mais je suis surpris que personne ne suggère un décorateur. XXX

J'ai vu un modèle similaire dans l'un des postes d'Alex Martelli, mais je Ne me souviens pas de la main de la liaison.


0 commentaires