Python的秘密生活:隐藏的返回
Source: Dev.to
为什么你的函数返回 None —— 以及如何修复它。
Timothy 看着屏幕时露出了笑容。他刚刚把定价脚本重构成整洁、有条理的函数,正如 Margaret 示范的那样。
“现在感觉干净多了,”他边说边点击 Run。 “看看它的运行效果。”
屏幕闪了一下。
Calculating Tax...
Tax is: 15.0
Final Price: None
Timothy 的笑容变成了真正的困惑。“这很奇怪,”他轻声说。 “最终价格是 None。但就在前一行,它已经打印了 15.0。我想知道这个数字去哪儿了?”
Margaret 抬起头微笑道。 “需要我再帮你看看吗?”
“请帮忙,” Timothy 说。 “我不确定自己漏掉了什么。在 calculate_tax 中,我计算了 tax 变量。它肯定是 15.0,因为我打印了它。但当我在主函数里使用它时,它好像消失了。”
他把代码给她看:
def calculate_tax(price, rate):
tax = price * rate
print(f"Tax is: {tax}")
def main():
price = 100
rate = 0.15
# Timothy expects 'tax_amount' to hold 15.0
tax_amount = calculate_tax(price, rate)
final_price = price + tax_amount
print(f"Final Price: {final_price}")
if __name__ == "__main__":
main()
隐式的 None
Margaret 友好地点了点头。 “我完全明白发生了什么。你已经完成了计算,但没有告诉函数把答案返回给你。”
她解释道: “Python 有一条不太起眼的规则。每个函数 必须 返回某些东西。如果我们没有显式指定返回什么,Python 会默认礼貌地返回 None。”
Timothy 恍然大悟:“所以当我写 tax_amount = calculate_tax(...) 时,我并没有捕获到 15.0,而是捕获了默认的 None?”
“正是,” Margaret 说。 “你算出了数值,打印给我们看,但函数在结束时没有把这个值‘递交’出去。”
交棒
“这说得通,” Timothy 说。 “所以我需要正式把数据返回。”
“没错,” Margaret 回答。 “我们使用 return 关键字。把它想象成接力赛。函数跑完自己的那一棒,return 就是把接力棒交给下一位选手的时刻。记住:一旦函数返回了值,它会立即停止运行。”
她帮他修改了代码:
def calculate_tax(price, rate):
tax = price * rate
return tax # Explicitly hand the value back
def main():
price = 100
rate = 0.15
# Now, the function hands back 15.0
tax_amount = calculate_tax(price, rate)
# And we can use it for math!
final_price = price + tax_amount
print(f"Final Price: {final_price}")
if __name__ == "__main__":
main()
Output
Final Price: 115.0
Timothy 笑了。“print 是给我看的,return 才是给代码的。”
Margaret 的速查表
- 概念: 数据流 vs. 副作用
- 陷阱: 误以为计算或打印一个值就会让它在程序的其他地方可用。
- 规则: 默认情况下,如果函数在没有
return语句的情况下执行到末尾,它会返回None。 - 修复: 使用
return将结果传回调用者。
print(x) # Show it to the human (Side Effect)
return x # Give it to the computer (Data Flow)
在下一集,Margaret 和 Timothy 将面对 “阴影名称”——Timothy 将学习为什么把变量命名为 list 或 str 会导致意想不到的问题。