在这种情况下我应该用什么代替全局变量?python3.8



我有一个相当大的项目,由于复杂性和隐私,我想把我的问题的意义贴出来。

def H():
B()
...
# return with something else
def G():
...
B()
# return with something else
def F():
dosomething(counter, ...)
...
def E():
...
def D():
...
B()
...
# return with something else
def C():
...
def B():
...
if success:
global counter += 1 
...

def A():
B()
C()
D() # the list goes on...
...

def main():
try:
A()
except Exception as e:
...
else:
...
counter = 0

if __name__ == '__main__':
main()

正如你所看到的,问题是有一个全局变量,每次调用B()的函数有一个成功的结果时,它就递增。

我做了关于stackoverflow的研究,大多数人都在诅咒全局变量,它们不是简单地用作内容,它们是邪恶的,应该不惜一切代价避免。

大多数人并没有真正解释其中的原因和主要原因,但是有些人解释说全局变量应该避免,因为这会增加复杂性,可读性和混乱,我完全理解,如果使用不当,我会看到。

作为一种解决方案,大多数人认为应该使用返回,特别是对于元组(返回两个值)。

然而,在我的情况下,项目相当大,我列出了使用全局变量和返回

的利弊列表在我的例子中使用全局变量的优点

  • 全局变量仅由一个函数递增,其他函数调用该变量,因此没有复杂性和混乱
  • 花费了我2行代码

使用全局变量的缺点

  • ?

在我的例子中使用返回值而不是全局变量的优点

  • ?

在我的例子中使用返回而不是全局变量的缺点

  • 我必须重写所有内容,因为我必须将counter传递给main,然后传递给D(), H(), B(), G(), A()。我必须重写函数内变量,以便它们使用正确的返回元素,我必须重写参数,我必须重写参数,我必须编辑类。简直是一团糟。

所以在我的情况下,我绝对不同意使用返回而不是全局变量。

使用全局变量->字面上的两行代码,简单易懂,直观。

Using返回->可能要重写50 - 100行代码,还要花时间修复类和对象,这增加了混乱和复杂性。

有什么我没看到的吗?你有什么想法吗?

简单使用全局计数器的问题是,特别是在大型项目中,很容易变得不清楚变量发生了什么。使用return可以更容易地调试和跟踪,因为您可以单独使用return语句并查看它们,也可以更容易地重用,因为您可以使用return语句(或其值)并重用它,甚至如果您需要/想要重新分配它。

现在,因为我们不知道你的函数到底是做什么的,除了基本结构之外,我们对代码几乎没有什么了解,所以很难给出明确的建议。

另一种选择是将变量放入类中,因为对象也是全局可调用的,但是更健壮。例如:

class B:
def __init__(self):
self.counter = 0
def increment_counter(self):
self.counter +=1
def get_counter(self):
return self.counter

然后创建一个对象,并在其他函数中调用对象函数。

最后,对于一些一般的建议,不要害怕重写代码,即使它可能会花费很多精力,如果它提供了代码质量的实质性改进。一个人可以在这个过程中学到很多东西,它可能会帮助你避免未来的错误。

如果我理解你的问题,那么你可能需要使用闭包。

由于B函数有条件地增加计数器,并且计数器在其他地方使用,您可能需要类似工厂函数的东西,它返回两个函数的元组,一个执行B,另一个返回counter的当前值。

像这样:

def factory():
counter = 0
def B():
...
if success:
counter += 1
...
def get_counter():
return counter
return (B, get_counter)

B, get_counter = factory()
// execute B
B()
// get the value of counter
current_counter = get_counter()

最新更新