Подтвердить что ты не робот

Идиоматический Python: цикл "times"

Скажем, у меня есть функция foo, которую я хочу вызвать n раз. В Ruby я бы написал:

n.times { foo }

В Python я могу написать:

for _ in xrange(n): foo()

Но это похоже на хакерский способ делать вещи.

Мой вопрос: есть ли идиоматический способ сделать это в Python?

4b9b3361

Ответ 1

Вопрос предполагает, что вызов foo() n раз является априорной необходимой задачей. Откуда я пришел? Это длина чего-то итерабельного? Затем повторите итерацию. Когда я набираю Python, я нахожу, что я использую мало для каких-либо произвольных значений; для вашего n есть более существенный смысл, который потерялся, когда он стал целым.

Ранее сегодня я столкнулся с провокационной статьей Nicklaus Wirth для IEEE Computer под названием Хорошие идеи - через зазеркалье (в архиве версия для будущих читателей). В разделе 4 он привносит другой уклон в программирование конструкций, которые все (включая самого себя) приняли как должное, но которые содержат выразительные недостатки:

"Общность алголов forвыражение должно было быть предупреждением сигнал всем будущим дизайнерам всегда сохраняют основную цель строить в уме и утомляться преувеличенной общности и сложности, который может легко стать непродуктивный".

Алгол for эквивалентен C/Java for, он просто делает слишком много. Этот документ полезен для чтения, хотя бы потому, что он делает так, что он не воспринимается как нечто само собой разумеющееся, что мы так легко делаем. Поэтому, возможно, лучший вопрос: "Зачем вам нужен цикл, который выполняется произвольным числом раз?"

Ответ 2

Вы уже показали идиоматический способ:

for _ in range(n): # or xrange if you are on 2.X
    foo()

Не уверен, что такое "хакерство". Если у вас более конкретный вариант использования, просьба указать более подробную информацию, и может быть что-то более подходящее для того, что вы делаете.

Ответ 3

Самый быстрый, самый чистый itertools.repeat:

import itertools

for _ in itertools.repeat(None, n):
    foo()

Ответ 4

Если вы хотите использовать метод times, и вам нужно использовать его для своих собственных функций, попробуйте следующее:

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

теперь добавьте декоратор @repeatable к любому методу, которому нужен метод times:

@repeatable
def foo(bar):
    print bar

foo.times(4, "baz") #outputs 4 lines of "baz"