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()

假设我有以下简化的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()
        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