Do you use the “global” statement in Python?
我在读关于python global语句("python scope")的一个问题,我还记得在我还是一个python初学者的时候(我经常使用global)使用这个语句的频率,以及几年后,我是如何永远不使用它的。我甚至认为它有点"非Python式"。
在python中使用这个语句吗?你对它的使用是否随时间而改变?
我在这样的上下文中使用"global":
1 2 3 4 5 6 7 8 9 10 | _cached_result = None def myComputationallyExpensiveFunction(): global _cached_result if _cached_result: return _cached_result # ... figure out result _cached_result = result return result |
我使用"全局"是因为它是有意义的,并且对函数的读者来说是清楚的。我也知道有这样的模式,这是等效的,但给读者带来了更多的认知负担:
1 2 3 4 5 6 7 8 9 | def myComputationallyExpensiveFunction(): if myComputationallyExpensiveFunction.cache: return myComputationallyExpensiveFunction.cache # ... figure out result myComputationallyExpensiveFunction.cache = result return result myComputationallyExpensiveFunction.cache = None |
在我3年以上专业使用Python的过程中,我从未在任何生产代码中合法使用过该语句,作为一个Python爱好者,我也有5年多的时间。我需要更改的任何状态都存在于类中,或者,如果存在一些"全局"状态,它就位于一些共享结构中,如全局缓存。
我已经在函数创建或设置变量的情况下使用了它,这些变量将全局使用。以下是一些例子:
1 2 3 4 5 6 7 8 | discretes = 0 def use_discretes(): #this global statement is a message to the parser to refer #to the globally defined identifier"discretes" global discretes if using_real_hardware(): discretes = 1 ... |
或
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | file1.py: def setup(): global DISP1, DISP2, DISP3 DISP1 = grab_handle('display_1') DISP2 = grab_handle('display_2') DISP3 = grab_handle('display_3') ... file2.py: import file1 file1.setup() #file1.DISP1 DOES NOT EXIST until after setup() is called. file1.DISP1.resolution = 1024, 768 |
在我看来,一旦您觉得有必要在Python代码中使用全局变量,就应该停一下,重新构造代码了。把
所以,老实说,即使是允许的,我也尽量避免使用它。即使它意味着围绕代码构建一个简单的类。
我将其用于带有命令行脚本和"optparse"的全局选项:
我的main()解析参数,并将其传递给执行脚本工作的任何函数…但将提供的选项写入全局"opts"字典。
shell脚本选项通常会调整"leaf"行为,并且不方便(也不必要)将"opts"字典贯穿到每个参数列表中。
对象是具有非本地状态的首选方式,因此很少需要全局。我不认为即将到来的非本地修改器也将被广泛使用,我认为它主要是为了让Lispers停止抱怨:—)
我在快速和肮脏的一次性脚本中使用它来自动执行某个一次性任务。任何比这更大的东西,或者需要重用的东西,我会找到一种更优雅的方式。
它可以在线程中用于共享状态(周围有锁定机制)。
然而,我很少使用它。
很少。我还没有找到它的用途。
我避免使用它,而且我们甚至有一个皮林特规则,在我们的生产代码中禁止使用它。我真的认为它根本不应该存在。
一次或两次。但重构始终是一个好的起点。
如果我能避免,不。据我所知,总有一种方法可以避免。但我也不是说这完全没用