2016-06-05 4 views
-1

Я хочу написать функцию обертки для eternity, которая заставит ее вести себя так, как будто ее лениво оценивают. Другими словами, его функциональность должна быть идентична ее функции lazyeternity ниже. У меня есть эта функция packageN, которая выполняет функцию и упаковывает ее в лямбда - или, по крайней мере, я думаю, что это так. (Упаковка lazyeternity внутри лямбда задерживает ее оценку в вызове etest.) Как я могу изменить packageN, так что eternity = packageN(eternity) может отражать поведение lazyeternity?Создание функции ленив в Python

def eternity(): 
     return eternity() 

    # How can I create a wrapper function for eternity... 
    # that will make it behave identical to this function? 
    def lazyeternity(): 
     return lambda: lazyeternity() 

    def packageN(f): 
     return lambda *x: f(*x) 

    def etest(x, y): 
     return x 

    eternity = packageN(eternity) 

    # I want these both to return 4. 
    # Currently only the first one returns 4,... 
    # because the second one evaluates the eternity()... 
    # parameter forever. I want to delay the evaluation... 
    # of the parameter. 
    print etest(4, lazyeternity()) 
    print etest(4, eternity()) 
+0

Вы можете добавить более конкретный пример того, как вы хотите использовать это? Код в вашем вопросе не имеет большого смысла. –

+0

Спасибо, @ Håken. Я попытался немного разъяснить, но дайте мне знать, могу ли я помочь. Я хочу иметь возможность применить 'packageN' к любой функции' f', чтобы сделать так, чтобы 'f' оценивался только тогда, когда это необходимо. – user1837378

ответ

2

Разница между lazyeternity и eternity, возвращаемый packageN является, что вызов lazyeternity возвращает лямбда, в то время как eternityявляется лямбда, который при вызове работает навсегда.

Чтобы packageN вернуть то, что действует как lazyeternity, сделать его

def packageN(f): 
    return lambda: lambda *x: f(*x) 
+0

Ничего себе, спасибо, это работает !! Но разве «packageN» не возвращал лямбду раньше? Если я напечатаю 'вечность' после запуска' eternity = packageN (вечность) ', используя либо мою версию' packageN', либо вашу версию, он говорит, что объект является лямбдой. – user1837378

+0

'packageN' возвращал лямбду, которая присваивается' вечности', поэтому вызов 'вечность' выполнял эту лямбду. В отличие от вызова 'lazyeternity', который просто дает вам лямбду (и не выполняет ее). Поэтому, чтобы сделать то же самое, 'packageN' должен вернуть лямбду, которая возвращает лямбда. – Kundor

+0

Будет ли это работать с функциями более высокого порядка? Я пытаюсь обернуть ленивое определение комбинатора Y, def Y (f): вернуть f (Y (f)) таким образом. – user1837378

1

Для того, чтобы как eternity работу, просто удалите (). Вы хотите вернуть функцию, а не оценку функции (бесконечный цикл).

+0

«Вечность» не должна работать в контексте «etest». Я хочу, чтобы функция-оболочка изменяла ее так, чтобы 'etest' мог работать с' вечностью' в качестве аргумента, если 'вечность' не используется (т. Е. Это второй аргумент в' etest'). – user1837378

Смежные вопросы