将全局变量传递给类和函数的替代方法

时间:2010-09-04 02:52:33

标签: python

我是python的新手,我一直在阅读使用global将变量传递给其他函数被认为是noobie,以及一个不好的做法。我想放弃使用全局变量,但我不知道该怎么做。

现在我有一个我在wxPython中创建的UI作为它自己独立的类,我有另一个类从.ini文件加载设置。由于UI中的设置应与.ini中的设置相匹配,如何传递这些值?我可以使用类似Settings = Settings()之类的东西,然后将变量定义为类似self.settings1的东西,但是我必须使Settings成为一个全局变量,将它传递给我的UI类(它如果我在其中分配main())则不会。

那么传递这些变量的正确和pythonic方法是什么?

编辑:这是我正在使用的代码,我正在努力让它像Alex Martelli的例子一样工作。以下代码保存在Settings.py

import ConfigParser

class _Settings():
    @property
    def enableautodownload(self): return self._enableautodownload
    def __init__(self):
        self.config = ConfigParser.ConfigParser()

        self.config.readfp(open('settings.ini'))
        self._enableautodownload=self.config.getboolean('DLSettings', 'enableautodownload')

settings = _Settings()

每当我尝试从另一个文件中引用Settings.settings.enableautodownload时,我会得到:AttributeError: 'module' object has no attribute 'settings'。我做错了什么?

编辑2:没关系这个问题,我重新输入了代码并且现在可以正常工作了,所以它一定是一个简单的拼写或语法错误。

1 个答案:

答案 0 :(得分:4)

global变量的替代品很多 - 主要是:

  • 函数的显式参数,调用它们创建其中一个实例的类等(这通常是最清楚的,因为它使得依赖关系最明确,在可行且不重复的时候);
  • 对象的实例变量,当需要访问这些值的函数是同一对象上的方法时(也没关系,以及使用OOP的合理方法);
  • 提供值的“访问器函数”(或具有值的属性或属性的对象)。

这些中的每一个(尤其是第一个和第三个)对于名称必须重新绑定所有和各种各样的值,但只能被访问的值特别有用。 global的一个非常大的问题是它提供了一个“隐蔽的通信渠道”(不是在加密意义上,而是在字面意义上:显然,单独的功能实际上可以相互依赖,通过全局相互影响函数签名中“不明显”的值 - 这使代码难以测试,调试,维护和理解。)

对于您的特定问题,如果您从不使用global语句,而是从任何地方以“只读”方式访问设置(并且您可以通过使所述对象的属性被读取来更加完整地确保 - 只有属性!),然后在一个单独的,一次性改变的模块级实例上执行“只读”访问,这不是太糟糕。即,在某个模块中foo.py

class _Settings(object):
    @property
    def one(self): return self._one
    @property
    def two(self): return self._two
    def __init__(self, one, two):
       self._one, self._two = one, two
settings = _Settings(23, 45)

以及其他任何地方,import foo然后根据需要访问foo.settings.onefoo.settings.two。请注意,我已经使用单个前导下划线命名该类(就像构成只读属性的两个实例属性一样),以表明它不是要从模块的“外部”使用 - 只有{{1对象应该是(没有强制执行 - 但是任何违反此类请求隐私的用户显然是唯一负责任何可能发生的混乱的一方; - 。)。