Boucle de Python idiomatique: 'times' [dupliquer]
cette question a déjà une réponse ici:
- est-il possible d'implémenter un python pour une boucle de portée sans variable itératrice? 15 réponses
Dire que j'ai une fonction foo
que je veux l'appeler "151930920." En Ruby, j'écrirais:
n.times { foo }
en Python, je pourrais écrire:
for _ in xrange(n): foo()
mais ça ressemble à une façon détournée de faire les choses.
ma question: y a-t-il une façon idiomatique de faire cela en Python?
4 réponses
la question présuppose qu'appeler foo () n times est une a priori chose nécessaire. Où avez-n vient? Est-ce la longueur de quelque chose itératif? Puis itérer sur le itérable. Comme je relève Python, je trouve que j'utilise peu ou pas de valeurs arbitraires; il y a un sens plus saillant derrière votre n qui s'est perdu quand il est devenu un entier.
plus tôt aujourd'hui, je suis arrivé sur Nicklaus Wirth provocateur de papier pour IEEE Computer droit les Bonnes Idées, à Travers le miroir (archivé version pour les futurs lecteurs). Dans la section 4, il présente un autre point de vue sur les concepts de programmation que tout le monde (y compris lui-même) a pris pour acquis, mais qui présentent des défauts expressifs:
"La généralité de l'Algol
for
déclaration aurait dû être un avertissement signal à tous les futurs designers gardez toujours l'objectif principal d'un construire dans l'esprit, et à se lasser de généralité et complexité exagérées, qui peut facilement devenir contre-productif."
l'algol for
est équivalent au C/Java for
, il fait tout simplement trop. Ce document est une lecture utile, ne serait-ce que parce qu'il fait qu'on ne tient pas tant pour acquis que nous le faisons si facilement. Donc peut-être une meilleure question est "Pourquoi vous avez besoin d'une boucle qui s'exécute un nombre arbitraire de fois?"
vous avez déjà montré la voie idiomatique:
for _ in range(n): # or xrange if you are on 2.X
foo()
Je ne sais pas ce qu'est "hackish" à propos de ça. Si vous avez un cas d'utilisation plus spécifique à l'esprit, veuillez fournir plus de détails, et il pourrait y avoir quelque chose de mieux adapté à ce que vous faites.
le plus rapide, le plus propre est itertools.répétez :
import itertools
for _ in itertools.repeat(None, n):
foo()
si vous voulez la méthode times
, et que vous devez l'utiliser sur vos propres fonctions, essayez ceci:
def times(self, n, *args, **kwargs):
for _ in range(n):
self.__call__(*args, **kwargs)
import new
def repeatable(func):
func.times = new.instancemethod(times, func, func.__class__)
return func
maintenant ajouter un @repeatable
décorateur à toute méthode vous avez besoin d'une times
méthode sur:
@repeatable
def foo(bar):
print bar
foo.times(4, "baz") #outputs 4 lines of "baz"