Python嵌套函数调用疑问:两种调用f2方式的差异解析
为什么直接调用f2()会报错,而(f1())()却能正常执行?
先看你的代码示例:
def f1(): X = 88 def f2(): print(X) return f2 action = f1() action()
你提到两种调用方式的差异:(f1())()能正常执行,直接f2()却会抛出NameError,报错信息如下:
Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'f2' is not defined
核心原因其实是Python的作用域规则,咱们拆解来看:
1. 直接调用f2()为什么不行?
你定义的f2是f1内部的嵌套函数,它的名字只存在于f1的局部作用域里。当你在全局作用域(也就是f1外面)直接敲f2()时,Python会在当前作用域(全局)找叫f2的名字,显然找不到,所以就抛出了NameError——就像你在自己家里喊邻居的名字,邻居肯定听不到啊,因为名字只在邻居家的“作用域”里。
2. (f1())()为什么能正常执行?
咱们把这个调用拆成两步看:
- 第一步:
f1()——执行f1函数,这时候f1内部会定义f2,然后把f2这个函数对象返回出来。这相当于你从邻居家拿到了邻居的联系方式(函数引用)。 - 第二步:调用返回的
f2对象——也就是(返回的f2)(),这时候你是在调用一个已经拿到手的函数引用,而且因为闭包的特性,f2还能记住f1内部的X=88这个变量,所以能正常打印出88。
简单说就是:直接f2()是在全局找不存在的名字,而(f1())()是先让f1生成并返回f2的引用,再调用这个引用,自然就能找到f2并执行了。
内容的提问来源于stack exchange,提问作者Pawandeep Singh
相关产品推荐
相关产品推荐

