我使用全局变量,但我读到它们不是一个很好的练习或奏鸣曲。我经常使用函数,因此我需要在主函数中使用许多yes/no变量。例如,如何在不使用全局变量的情况下编写以下代码?
def secondary_function():
global alfa_is_higher_than_12
global beta_is_higher_than_12
alfa = 12
beta = 5
if alfa > 10:
alfa_is_higher_than_12 = "yes"
else:
alfa_is_higher_than_12 = "no"
if beta > 10:
beta_is_higher_than_12 = "yes"
else:
beta_is_higher_than_12 = "no"
def main_function():
global alfa_is_higher_than_12
global beta_is_higher_than_12
secondary_function()
if alfa_is_higher_than_12=="yes":
print("alfa is higher than 12")
else:
print("alfa isn't higher than 12")
if beta_is_higher_than_12=="yes":
print("beta is higher than 12")
else:
print("beta isn't higher thant 12")
main_function()发布于 2019-12-13 22:36:04
人们可能会问,您可能需要这样构造代码的原因是什么,但假设您有自己的原因,您可以只从次要函数返回值:
def secondary_function():
alfa = 12
beta = 5
if alfa > 10:
alfa_is_higher_than_12 = "yes"
else:
alfa_is_higher_than_12 = "no"
if beta > 10:
beta_is_higher_than_12 = "yes"
else:
beta_is_higher_than_12 = "no"
return alfa_is_higher_than_12, beta_is_higher_than_12
def main_function():
alfa_is_higher_than_12, beta_is_higher_than_12 = secondary_function()
if alfa_is_higher_than_12=="yes":
print("alfa is higher than 12")
else:
print("alfa isn't higher than 12")
if beta_is_higher_than_12=="yes":
print("beta is higher than 12")
else:
print("beta isn't higher thant 12")发布于 2019-12-13 22:46:14
术语"毕多尼“不适用于这个主题--在任何编程语言和范例中使用这样的全局语言都是很糟糕的实践,而不是特定于Python的东西。
global关键字是Python提供的工具,可以让您选择退出封装并打破变量的自然作用域。封装意味着您的每个组件都是一个逻辑的、独立的单元,它应该作为一个黑匣子和做一件事工作(注意:这一件事是概念性的,可以由许多可能是非平凡的子步骤组成),而不需要改变全局状态或生成副作用。其原因是模块化:如果程序(和它会的)出现问题,强大的封装使确定失败组件的位置变得非常容易。
封装使代码更易于重构、维护和扩展。如果您需要组件的行为不同,应该很容易删除或调整它,而不需要这些修改导致系统中其他组件更改的多米诺效应。
执行封装的基本工具包括类、函数、参数和return关键字。语言通常提供类似的模块、命名空间和闭包,但最终目标总是限制范围并允许程序员创建松散耦合的抽象。
函数通过参数接收输入,通过返回值生成输出。可以将返回值分配给调用范围中的变量。您可以将参数看作调整函数行为的“旋钮”。在函数内部,变量只是函数所需的临时存储,以生成其一个返回值,然后消失。
理想情况下,函数编写为纯正和幂等;也就是说,它们不会修改全局状态,并在多次调用时产生相同的结果。Python对此的要求比其他语言稍低一些,使用某些就地函数(如sort和random.shuffle )是很自然的。这些异常证明了规则(如果您对排序和洗牌有一点了解的话,由于所使用的算法和效率的需要,它们在这些上下文中是有意义的)。
就地算法是不纯的和非幂等的,但是如果它修改的状态仅限于它的参数,并且它的文档和返回值(通常是None)支持这一点,则行为是可预测的和可理解的。
那么,这一切在代码中是什么样子的呢?不幸的是,您的示例似乎是人为的,并且不清楚它的目的/目标,因此没有直接的方法来转换它,从而使封装的优点变得显而易见。
下面列出了这些函数中除了修改全局状态之外的一些问题:
"yes"和"no"字符串文本,而不是True/False布尔值。printing (请参阅上面的副作用注释--如果他们想这样做的话,更愿意返回值并让调用范围打印)。secondary_function这样的通用变量名(我假设这相当于foo/bar的例子,但仍然不能证明它们存在的理由,因此很难将其作为教学示例加以修改)。但无论如何,这是我的机会:
if __name__ == "__main__":
alpha = 42
beta = 6
print("alpha %s higher than 12" % ("is" if alpha > 12 else "isn't"))
print("beta %s higher than 12" % ("is" if beta > 12 else "isn't"))我们可以看到,不需要所有的函数--只要在需要比较的地方编写alpha > 12,并在需要打印时调用print。函数的一个缺点是它们可以隐藏重要的逻辑,所以如果它们的名称和“契约”(由名称、文档串和参数/返回值定义)不清楚,它们只会混淆函数的客户端(通常是自己)。
为了举例说明,假设您经常调用此格式化程序。然后,有理由进行抽象;调用代码将变得很麻烦,并且会变得重复。您可以将格式化代码移动到助手函数,并将任何要注入模板的动态数据传递到模板中:
def fmt_higher(name, n, cutoff=12):
verb = "is" if n > cutoff else "isn't"
return f"{name} {verb} higher than {cutoff}"
if __name__ == "__main__":
print(fmt_higher("alpha", 42))
print(fmt_higher("beta", 6))
print(fmt_higher("epsilon", 0))
print(fmt_higher(name="delta", n=2, cutoff=-5))我们可以更进一步,假装n > cutoff是一个更加复杂的测试,如果将其留在fmt_higher中,那么许多小步骤将违背单一责任。也许在代码的其他地方使用了复杂的测试,并且可以推广到支持这两个用例。
在这种情况下,您仍然可以使用参数和返回值来代替global,并对谓词执行与格式化程序相同的抽象:
def complex_predicate(n, cutoff):
# pretend this function is much more
# complex and/or used in many places...
return n > cutoff
def fmt_higher(name, n, cutoff=12):
verb = "is" if complex_predicate(n, cutoff) else "isn't"
return f"{name} {verb} higher than {cutoff}"
if __name__ == "__main__":
print(fmt_higher("alpha", 42))
print(fmt_higher("beta", 6))
print(fmt_higher("epsilon", 0))
print(fmt_higher(name="delta", n=2, cutoff=-5))只有当有足够的理由进行抽象时(调用代码被阻塞,或者当您多次重复类似的代码块时,才是经典的经验法则)。当你做抽象的时候,做适当地。
发布于 2019-12-13 22:37:15
永远不要写“全球”。那么,您肯定没有引入任何全局变量。
还可以将这些值作为参数传递:
def secondary_function():
alfa = 12
beta = 5
if alfa > 10:
alfa_is_higher_than_12 = "yes"
else:
alfa_is_higher_than_12 = "no"
if beta > 10:
beta_is_higher_than_12 = "yes"
else:
beta_is_higher_than_12 = "no"
return alfa_is_higher_than_12, beta_is_higher_than_12
def main_function(alfa_is_higher_than_12, beta_is_higher_than_12):
if alfa_is_higher_than_12=="yes":
print("alfa is higher than 12")
else:
print("alfa isn't higher than 12")
if beta_is_higher_than_12=="yes":
print("beta is higher than 12")
else:
print("beta isn't higher thant 12")
main_function(*secondary_function())https://stackoverflow.com/questions/59330578
复制相似问题