python:在乘法运行方法中使用类变量作为计数器
假设我有以下简化的python代码:python:在乘法运行方法中使用类变量作为计数器,python,recursion,Python,Recursion,假设我有以下简化的python代码: class GUI: def __init__(self): self.counter = 0 self.f1c = 0 self.f2c = 0 def update(self): self.counter = self.counter + self.f1() self.counter = self.counter + self.f4()
class GUI:
def __init__(self):
self.counter = 0
self.f1c = 0
self.f2c = 0
def update(self):
self.counter = self.counter + self.f1()
self.counter = self.counter + self.f4()
self.counter = self.counter + self.f2()
self.counter = self.counter + self.f3()
print(self.counter)
if (self.counter > 4):
print("doing update now")
# do_update()
self.counter = 0
def f1(self):
if self.f1c < 2:
self.f1c = self.f1c + 1
self.update()
return 1
def f2(self):
if self.f2c < 4:
self.f2c = self.f2c + 1
self.update()
return 0
def f3(self):
return 1
def f4(self):
return 0
g = GUI()
g.update()
虽然我希望它是:
1
2
3
4
5
doing update now
0
1
据我所知,在我的代码示例中,self.counter
甚至不可能在不执行do\u update()
的情况下从2
变为1
正确的方法是什么
编辑:基本上,我想要的是,
do\u update
只会在所有其他函数结束后运行和计数器>0
这里有一些非常复杂的递归,老实说,我认为你没有创建无限循环是幸运的
为了了解您所拥有的一切,我使用调试器打开了您的代码,并对调用进行了注释,以跟踪通过前两个print语句的流顺序。增加缩进表示嵌套函数调用更深,然后列出带有行本身的行号。注释指示每个阶段某些变量的当前值,并指示打印语句发生的时间:
--Call-- 39| g.update()
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 0
--Call-- 22| self.update() #f1c is 1
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 1
--Call-- 22| self.update() #f1c is 2
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 2
--Return-- 23| return 1 #self.counter now == 1
--Call-- 09| self.counter = self.counter + self.f4()
--Return-- 35| return 0 #self.counter now == 1
--Call-- 10| self.counter = self.counter + self.f2() #f2c is 0
--Call-- 28| self.update() #f2c is 1
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 2
--Return-- 23| return 1 #self.counter now == 2
--Call-- 09| self.counter = self.counter + self.f4()
--Return-- 35| return 0 #self.counter now == 2
--Call-- 10| self.counter = self.counter + self.f2() #f2c is 1
--Call-- 28| self.update() #f2c is 2
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 2
--Return-- 23| return 1 #self.counter now == 3
--Call-- 09| self.counter = self.counter + self.f4()
--Return-- 35| return 0 #self.counter now == 3
--Call-- 10| self.counter = self.counter + self.f2() #f2c is 2
--Call-- 28| self.update() #f2c is 3
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 2
--Return-- 23| return 1 #self.counter now == 4
--Call-- 09| self.counter = self.counter + self.f4()
--Return-- 35| return 0 #self.counter now == 4
--Call-- 10| self.counter = self.counter + self.f2() #f2c is 3
--Call-- 28| self.update() #f2c is 4
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 2
--Return-- 23| return 1 #self.counter now == 5
--Call-- 09| self.counter = self.counter + self.f4()
--Return-- 35| return 0 #self.counter now == 5
--Call-- 10| self.counter = self.counter + self.f2() #f2c is 4
--Return-- 29| return 0 #self.counter now == 5
--Call-- 11| self.counter = self.counter + self.f3()
--Return-- 32| return 1 #self.counter now == 6
### print(self.counter) ### #self.counter now == 6
### print('doing update')
#self.counter now == 0
--Return-- 18| #self.counter in prior stack frame was only 4
--Return-- 29| return 0 #self.counter now == 4
--Call-- 11| self.counter = self.counter + self.f3()
--Return-- 32| return 1 #self.counter now == 5
### print(self.counter) ### #self.counter now == 5
### print('doing update')
#self.counter now == 0
--Return-- 18| #self.counter in prior stack frame was only 3
你需要提供一个新的解决方案。最简单的解释是你错了,函数调用()
有时会返回-1
。哦,等等,我错过了这一部分:“然后他们在某些情况下再次调用更新()
函数”。这意味着您看到的是子递归调用的结果,而不是父递归调用的结果,这很有意义。但是,请提供一个MRE,这样我们就可以挑逗出到底发生了什么,并提供一个解决方案。这将是一项艰苦的工作,但我会尝试!好吧,我重写了我的问题,希望它仍然符合我的实际代码…在f1()
--f4()
函数中添加一些打印语句。它将帮助你了解正在发生的事情。在到达打印任何内容的update()
部分之前,您正在结束递归调用。太棒了!是的,它是复杂的代码。我的项目总是以这样一种方式写的:它总是会结束,没有无限循环。因此,我的问题是,如何使我的计数器变量全局化,使其达到我所希望的效果?@larwain我仍然不太清楚您打算如何增加self.counter
。在我看来,基于这样的措辞,update
不应该修改self.counter
,除非它将其重置为0。按f1-f4的返回值递增的行是递归问题的所在。你的意思是要在f
函数中增加self.counter
,然后调用update检查它是否需要“立即执行更新”?当我运行update()
时,通常会再次递归调用同一函数。我想要的是:只有当至少一个其他函数的返回值大于0并且只有在所有其他函数结束后,do\u update
部分才会执行。
--Call-- 39| g.update()
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 0
--Call-- 22| self.update() #f1c is 1
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 1
--Call-- 22| self.update() #f1c is 2
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 2
--Return-- 23| return 1 #self.counter now == 1
--Call-- 09| self.counter = self.counter + self.f4()
--Return-- 35| return 0 #self.counter now == 1
--Call-- 10| self.counter = self.counter + self.f2() #f2c is 0
--Call-- 28| self.update() #f2c is 1
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 2
--Return-- 23| return 1 #self.counter now == 2
--Call-- 09| self.counter = self.counter + self.f4()
--Return-- 35| return 0 #self.counter now == 2
--Call-- 10| self.counter = self.counter + self.f2() #f2c is 1
--Call-- 28| self.update() #f2c is 2
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 2
--Return-- 23| return 1 #self.counter now == 3
--Call-- 09| self.counter = self.counter + self.f4()
--Return-- 35| return 0 #self.counter now == 3
--Call-- 10| self.counter = self.counter + self.f2() #f2c is 2
--Call-- 28| self.update() #f2c is 3
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 2
--Return-- 23| return 1 #self.counter now == 4
--Call-- 09| self.counter = self.counter + self.f4()
--Return-- 35| return 0 #self.counter now == 4
--Call-- 10| self.counter = self.counter + self.f2() #f2c is 3
--Call-- 28| self.update() #f2c is 4
--Call-- 08| self.counter = self.counter + self.f1() #f1c is 2
--Return-- 23| return 1 #self.counter now == 5
--Call-- 09| self.counter = self.counter + self.f4()
--Return-- 35| return 0 #self.counter now == 5
--Call-- 10| self.counter = self.counter + self.f2() #f2c is 4
--Return-- 29| return 0 #self.counter now == 5
--Call-- 11| self.counter = self.counter + self.f3()
--Return-- 32| return 1 #self.counter now == 6
### print(self.counter) ### #self.counter now == 6
### print('doing update')
#self.counter now == 0
--Return-- 18| #self.counter in prior stack frame was only 4
--Return-- 29| return 0 #self.counter now == 4
--Call-- 11| self.counter = self.counter + self.f3()
--Return-- 32| return 1 #self.counter now == 5
### print(self.counter) ### #self.counter now == 5
### print('doing update')
#self.counter now == 0
--Return-- 18| #self.counter in prior stack frame was only 3