Disons que j'ai une fonction foo
que je veux appeler n
fois. En Ruby, j'écrirais:
n.times { foo }
En Python, je pourrais écrire:
for _ in xrange(n): foo()
Mais cela semble être une manière hacky de faire les choses.
Ma question: existe-t-il une façon idiomatique de le faire en Python?
La question présuppose que l'appel de foo () n fois est une chose a priori nécessaire. D'où vient-il? Est-ce la longueur de quelque chose d'itérable? Ensuite, parcourez l'itérable. Comme je prends 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 dans la journée, je suis tombé sur l'article provocateur de Nicklaus Wirth pour IEEE Computer intitulé Bonnes idées - à travers le miroir (archivé version pour les futurs lecteurs) . Dans la section 4, il apporte une perspective différente sur les constructions de programmation que tout le monde (y compris lui-même) a prises pour acquis mais qui contiennent des défauts expressifs:
"La généralité de la déclaration
for
d'ALGOL aurait dû être un signal d'avertissement pour tous les futurs concepteurs afin de toujours garder à l'esprit l'objectif principal d'une construction et de se lasser d'une généralité et d'une complexité exagérées, qui peuvent facilement devenir productif."
ALGOL for
est équivalent au C/Java for
, il en fait juste trop. Ce document est utile à lire, ne serait-ce que parce qu'il fait que l'on ne tient pas tant pour acquis que nous le faisons si facilement. Alors peut-être une meilleure question est "Pourquoi auriez-vous 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 qui est "hackish" à ce sujet. 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.
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
ajoutez maintenant un @repeatable
décorateur pour toute méthode sur laquelle vous avez besoin d'une méthode times
sur:
@repeatable
def foo(bar):
print bar
foo.times(4, "baz") #outputs 4 lines of "baz"
Le plus rapide et le plus propre est itertools.repeat :
import itertools
for _ in itertools.repeat(None, n):
foo()