|
发表于 2018-4-26 15:26:08
|
显示全部楼层
本帖最后由 ABC23 于 2018-4-26 16:06 编辑
递归是自己调用自己,这里调用new_int的父类方法,不属于本类方法,故不是递归(这是定义)。
====================================================
BUT!定义是不完美的,除了自己调用自己,要增加函数调用栈的深度,还可以这样——函数间的循环调用!
public class Bar{
void f(){
g();
}
void g(){
f();
}
public static void main(String[] args) {
new Bar().f();
// new Bar().g();
}
}
用Java写的,明白这么回事就可以了。( 抛出java.lang.StackOverflowError)
但是,但是!Python和Java不一样,循环引用函数通常并不会增加额外的函数调用栈的深度,请看下面的例子。
>>> class Demo:
def f(self):
return g()
def g(self):
return f()
>>> d = Demo()
>>> dir(d)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'f', 'g']
>>> d.f()
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
d.f()
File "<pyshell#20>", line 3, in f
return g()
NameError: name 'g' is not defined
>>> d.g()
Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
d.g()
File "<pyshell#20>", line 5, in g
return f()
NameError: name 'f' is not defined
>>>
它只是说【函数未定义】,为什么呢,因为Python是动态语言,在进行时动态解释,首先加载f,运行中调用g就去找g。这个顺序和执行的顺序有关而和代码的摆放位置没有直接关系。
但是Java,是静态语言,代码写好了要编译的。不管你要不要运行加载f、g,都给你先加载着再说。
>>> from dis import dis
>>> dis(f)
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
dis(f)
NameError: name 'f' is not defined
>>> dis(g)
Traceback (most recent call last):
File "<pyshell#27>", line 1, in <module>
dis(g)
NameError: name 'g' is not defined
>>>
想要得到f、g的字节码?不可能的!这并不是无限递归引起的异常,而是根本没有定义!这一点也可以看出,Python是一个解释语言。无误。
你说的问题属于函数间的相互引用,但是要分清具体语言,在Python中这是行不通的
ps. 上面的例子Java换成C,也许更有说服力
pps. 补充,Python说不能实现函数循环引用,仅仅是针对类而言(方法),如果出了类,作为【一等公民】的Python函数,还是可以实现无穷引用的。
>>> def f():
g()
>>> def g():
f()
>>> from dis import dis
>>> dis(f)
2 0 LOAD_GLOBAL 0 (g)
2 CALL_FUNCTION 0
4 POP_TOP
6 LOAD_CONST 0 (None)
8 RETURN_VALUE
>>> dis(g)
2 0 LOAD_GLOBAL 0 (f)
2 CALL_FUNCTION 0
4 POP_TOP
6 LOAD_CONST 0 (None)
8 RETURN_VALUE
>>>
这就不是未定义了。 |
|