我有一个相当大的项目,由于复杂性和隐私,我想把我的问题的意义贴出来。
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()