python - python中全局变量的频率?

标签 python

Stack Overflow 有很多关于 python 中的全局变量的问题,它似乎给来自其他语言的人带来了一些困惑。范围规则并不完全按照许多来自其他背景的人所期望的方式发挥作用。

与此同时,代码的组织方式与其说是类级别,不如说是模块级别。因此,当所有内容不一定都包含在类中时,可以在成员变量中找到的状态可以放在模块级变量中。

所以我的问题分为两部分:

1) 我应该避免使用全局变量(特别是在函数内部设置它们并使用 global 关键字)吗?

2) 如果#1 是肯定的,是否有预期使用它们的通用模式?

我在一个有很多不同语言的地方工作,我想减少混淆并确保 pythonistas 以后不会讨厌我。

感谢您的任何建设性意见。

最佳答案

我强烈建议您阅读这篇标题为 Singletons and their Problems in Python 的博文.它让我重新考虑我对全局变量的使用。一些选择报价:

But beware. Just because you do not implement the singleton design pattern it does not mean you avoid the core problem of a singleton. The core problem of a singleton is the global, shared state. A singleton is nothing more than a glorified global variable and in languages like Java there are many reasons why you would want to use something like a singleton. In Python we have something different for singletons, and it has a very innocent name that hides the gory details: module.

That's right folks: a Python module is a singleton. And it shares the same problems of the singleton pattern just that it's a little bit worse.

下面是具有这种共享状态可能导致的问题的一个示例:

In order to not talk about irrelevant things, let's have a look at one of the modules from the standard library, the mimetypes module.

Have a look:

inited = False

def init(files=None):
    global inited
    db = MimeTypes()
    ...

This is actual code from the mimetypes module that ships with Python, just with the more gory details removed. The point is, there is shared state. And the shared state is a boolean flag that is True if the module was initialized or False if it was not. Now that particular case is probably not that problematic (trust me, it is) because mimetypes initializes itself, but you can see that there is a files parameter to the init function. If you pass a list of files to that function, it will reinitialize the mime database in memory with the mime information from those files. Now imagine what would happen if you have two libraries initializing mimetypes with two different sources …

这是一个足够常见的模式,我自己也做过……但例如,更好的方法是:init 返回一个实现所有方法的类的实例,而代码的其他部分可以 init 来获得具有不同参数的不同实例,这些实例不会干扰前者。 “缺点”是您必须将此实例传递给任何不想初始化新实例的代码,但该“缺点”的优点是它使您的依赖项变得显而易见。

总之,简而言之,我会尽量避免它,但如果您对具有隐式单例的代码没问题,那就去做吧。

关于python - python中全局变量的频率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12642624/

相关文章:

python - 将 groupby 输出到 csv 文件 pandas

python Selenium 元素不可见

python - 使用 OneVsRestClassifier 时 sklearn.svm.SVC 的哪个 decision_function_shape?

python 解析带双引号的json数据

python - 运行 Django 服务器时如何订阅 GCP Pub/Sub?

python - 强制Python释放对象以释放内存

python - Tkinter PIL 图像不显示在函数内部

python - 在 Pandas 中从 datetime <[M8] 删除时间

python - 如何在 Jinja2 HTML 模板中不使用 JavaScript 将用户重定向到另一个网页?

python - 如何在pygame中防止垃圾邮件子弹