Python代码正常输出却报NoneType对象不可调用错误排查
问题现象
完成《Think Python》绘制网格习题时,编写的代码可以正常输出预期网格图案,但运行末尾会抛出TypeError: 'NoneType' object is not callable错误。
原代码如下:
blank = " " plus = "+" minus = "-" slash = "|" def grid_kernel(f_p_m, f_s, f_b, p, m, b, s): f_p_m(p, m, b) f_b(b) f_s(s, b) f_b(b) f_s(s, b) f_b(b) f_s(s, b) f_b(b) f_s(s, b) f_b(b) def print_grid(f_kernel, f_p_m, p, m, b, s): f_kernel(p, m, b, s) f_kernel(p, m, b, s) f_p_m(p, m, b) def print_plus_minus(p, m, b): print(p, b, m, b, m, b, m, b, m, b, p, b, m, b, m, b, m, b, m, b, p) def print_slash(s, b): print(s, b, b, b, b, b, b, b, b, b, s, b, b, b, b, b, b, b, b, b, s) def print_blank(b): print(b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b) print_grid(grid_kernel(print_plus_minus, print_slash, print_blank, plus, minus, blank, slash), print_plus_minus(plus, minus, blank), plus, minus, blank, slash)
运行输出及报错:
+ - - - - + - - - - + | | | | | | | | | | | | + - - - - + - - - - + Traceback (most recent call last): File "/mypath/myfile.py", line 146, in <module> print_grid(grid_kernel(print_plus_minus, print_slash, print_blank, plus, minus, blank, slash), print_plus_minus(plus, minus, blank), plus, minus, blank, slash) File "/mypath/myfile.py", line 129, in print_grid f_kernel(p, m, b, s) TypeError: 'NoneType' object is not callable
错误根因
Python中函数是一等对象,定义后可以作为参数传递,但传参时如果给函数加了括号和实参,会提前执行该函数,把函数返回值作为实参传入;如果函数没有显式写return语句,默认返回值是None。
最后调用print_grid时的问题就出在这里:
- 第一个参数写的是
grid_kernel(print_plus_minus, print_slash, print_blank, plus, minus, blank, slash):这行代码会在传参阶段立刻执行grid_kernel函数,执行完没有返回值,得到None,传给print_grid的形参f_kernel。这也是为什么还没进到print_grid内部,就已经输出了一半网格内容。 - 第二个参数写的是
print_plus_minus(plus, minus, blank):同理,传参阶段立刻执行print_plus_minus,返回None传给形参f_p_m。
等代码进入print_grid函数内部,执行第一行f_kernel(p, m, b, s)时,f_kernel本质是None,自然就抛出了“NoneType对象不可调用”的错误。
修复方案
修改最后一行的print_grid调用,前两个参数直接传函数本身,不要提前加括号调用:
# 错误写法 # print_grid(grid_kernel(print_plus_minus, print_slash, print_blank, plus, minus, blank, slash), print_plus_minus(plus, minus, blank), plus, minus, blank, slash) # 正确写法 print_grid(grid_kernel, print_plus_minus, plus, minus, blank, slash)
修改后运行代码,会正常输出完整的2x2网格,不会抛出任何错误。
内容的提问来源于stack exchange,提问作者NonSleeper
相关产品推荐
相关产品推荐

