2017-01-30 5 views
2

Я изучаю Python, и я читаю «Think Python» и делаю несколько простых упражнений, включенных в книгу.Функция в Python дает сообщение об ошибке

Меня спрашивают: «Определите новую функцию, называемую do_four, которая принимает объект функции и значение и вызывает функцию четыре раза, передавая значение в качестве параметра».

Я пытаюсь создать эту функцию с помощью одного оператора, вызвав функцию, уже определенную как do_twice(), и протестировать ее с помощью функции print_double(). Вот код:

def do_twice(f, x): 
    f(x) 
    f(x) 

def do_four(f, v): 
    do_twice(do_twice(f, v), v) 

def print_twice(s): 
    print s 
    print s 

s = 'abc' 

do_four(print_twice, s) 

Этот код выдает ошибку:

abc 
abc 
abc 
abc 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-41-95b513e5e0ee> in <module>() 
----> 1 do_four(print_twice, s) 

<ipython-input-40-100f8587f50a> in do_four(f, v) 
     1 def do_four(f, v): 
----> 2  do_twice(do_twice(f, v), v) 

<ipython-input-38-7143620502ce> in do_twice(f, x) 
     1 def do_twice(f, x): 
----> 2  f(x) 
     3  f(x) 

TypeError: 'NoneType' object is not callable 

Пытаясь понять, что происходит, я пытался построить диаграмму стека, как описано в книге. Вот оно:

enter image description here

Не могли бы вы объяснить, сообщение об ошибке и комментарий на Stack диаграмме?

Ваш совет будет оценен по достоинству.

ответ

2

do_twice получает функцию по первому аргументу и ничего не возвращает. Таким образом, нет никаких оснований принимать do_twice результат do_twice. Вам необходимо передать его a function.

Это будет делать то, что вы имели в виду:

def do_four(f, v): 
    do_twice(f, v) 
    do_twice(f, v) 

Очень похоже на то, как вы определили do_twice по f

1
do_twice(do_twice(f, v), v) 
     ^^^^^^^^^^^^^^ 

Слегка переписано:

result = do_twice(f, v) 
do_twice(result, v) 

можно передать возвращаемое значение do_twice(...) в качестве первого параметра do_twice(...). Этот параметр должен быть функциональным объектом. do_twice не возвращение ничего, поэтому result - это None, который вы передаете вместо ожидаемого функционального объекта.

Здесь нет смысла размещать два do_twice.

0
do_twice(do_twice(f, v), v) 

Вы не можете передавать do_twice(f,v) в качестве параметра функции, потому что она ничего не возвращает.

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