我正在阅读一个关于 Python全局语句(“Python 范围”)的问题,我想起了当我还是 Python 初学者时我使用这个语句的频率(我经常使用全局),以及多年后的今天,我是如何做到的永远不要使用它。我什至认为它有点“非pythonic”。
你在 Python 中使用这个语句吗?您对它的使用是否随着时间而改变?
我正在阅读一个关于 Python全局语句(“Python 范围”)的问题,我想起了当我还是 Python 初学者时我使用这个语句的频率(我经常使用全局),以及多年后的今天,我是如何做到的永远不要使用它。我什至认为它有点“非pythonic”。
你在 Python 中使用这个语句吗?您对它的使用是否随着时间而改变?
我在这样的上下文中使用“全局”:
_cached_result = None
def myComputationallyExpensiveFunction():
global _cached_result
if _cached_result:
return _cached_result
# ... figure out result
_cached_result = result
return result
我使用“全局”是因为它是有意义的,并且函数的读者很清楚正在发生什么。我也知道有这种模式,它是等效的,但会给读者带来更多的认知负担:
def myComputationallyExpensiveFunction():
if myComputationallyExpensiveFunction.cache:
return myComputationallyExpensiveFunction.cache
# ... figure out result
myComputationallyExpensiveFunction.cache = result
return result
myComputationallyExpensiveFunction.cache = None
在我专业使用 Python 的 3 年多和作为 Python 爱好者五年多的时间里,我从未在任何生产代码中合法使用过该语句。我需要更改的任何状态都驻留在类中,或者,如果有一些“全局”状态,它位于一些共享结构中,例如全局缓存。
我在函数创建或设置将全局使用的变量的情况下使用它。这里有些例子:
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
...
或者
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 代码中使用全局变量,现在是停下来重新重构代码的好时机。
如果你的截止日期很近,将global
代码放入代码并延迟重构过程可能听起来很有希望,但是,相信我,除非你真的必须这样做,否则你不会回到这个并修复 - 就像你的代码停止工作一样奇怪的原因,你必须调试它,你遇到一些global
变量,它们所做的只是把事情搞砸。
所以,老实说,即使它是允许的,我也会尽可能避免使用它。即使这意味着围绕您的代码构建一个简单的类。
对象是具有非本地状态的首选方式,因此很少需要全局。我认为即将到来的非本地修饰符也不会被广泛使用,我认为它主要是为了让 lispers 停止抱怨:-)
我将它用于带有命令行脚本和“optparse”的全局选项:
我的 main() 解析参数并将它们传递给执行脚本工作的任何函数......但将提供的选项写入全局“opts”字典。
Shell 脚本选项经常调整“叶子”行为,并且通过每个参数列表将“选择”字典线程化是不方便的(并且不必要)。
我避免使用它,我们甚至有一条pylint规则在我们的生产代码中禁止它。我实际上认为它根本不应该存在。
很少。我还没有找到它的用途。
它在线程中用于共享状态(周围有锁定机制)很有用。
但是,我很少使用它。
我已经在快速而肮脏的一次性脚本中使用它来自动化一些一次性任务。任何比这更大的东西,或者需要重用的东西,我会找到一种更优雅的方式。
一次或两次。但它始终是重构的好起点。
如果我能避免它,不。而且,据我所知,总有办法避免它。但我也不是说它完全没用