Pylint - “使用全局声明”

时间:2012-08-28 04:52:27

标签: python global-variables warnings pylint

我正在努力研究当前的python程序是否非常清楚pylint警告,所以当我意识到我可以简单地关闭警告时,我想确保在我做之前没有更理想的解决方案。

我当前的代码部分是我的日志代码。我有一个函数init()设置处理程序并将它们附加到根记录器,函数set_console_level(level)设置控制台消息的报告级别(DEBUG,INFO等):< / p>

_CONSOLE_OUT = NONE

def init():
    """Set up the error handlers for the root logger"""
    console_out = logging.StreamHandler()
    console_out.setLevel(logging.INFO)  #Show info messages for now
    #...
    logging.root.addHandler(console_out)
    global _CONSOLE_OUT
    _CONSOLE_OUT = console_out

    #Rest of function sets up more handlers similarly
init()

def set_console_level(level):
    """Change the level at which console messages are printed"""
    assert __CONSOLE_OUT is not None #Set in init
    _CONSOLE_OUT.setLevel(level) 

据我所知,这是实现这一目标的方法。需要行global _CONSOLE_OUT才能写入模块级变量。但是,当我在此文件上运行pylint时,我收到警告W: 15,4:init: Using the global statement。有没有办法避免这种警告?解决这个问题的更好方法是什么?

(请不要在没有说明理由的情况下说global _CONSOLE_OUT #pylint: disable=W****

3 个答案:

答案 0 :(得分:2)

您可以在导入时创建它:

_console_out = ConsoleHandler()

其中ConsoleHandler是工厂函数或您的类,用于创建和设置处理程序。

答案 1 :(得分:1)

这是在方法范围之外设置项目的奇怪模式。它会在以后导致问题,因为你不知道从哪里设置全局变量。

您的代码也依赖于执行方法的顺序来设置变量 - 可能 - 代码的其他部分依赖于变量。如果您忘记调用init(),尤其是在导入内容时,这可能会导致问题(当然您可以始终将其粘贴在__init__.py中,但这不是重点)。

鉴于这些,我认为另一种方法是创建一个类并在类中设置变量(给它另一个命名空间);或者如果你想保持原样,塞巴斯蒂安建议返回配置变量。

如果需要设置多个元组,可以返回一个元组,然后将其解压缩以创建全局变量。

>>> def foo():
...   return "hello","world"
...
>>> a,b = foo()

答案 2 :(得分:0)

我想到看代码的一件事(以及Burhan Khalid的答案)是因为我没有理由将我的init()代码 完全放在一个函数中只是意味着它在导入时运行一次。我相信我最初这样做的唯一原因是处理程序变量不是模块级的。

所以我的代码可能只是

_CONSOLE_OUT = logging.StreamHandler()
_CONSOLE_OUT.setLevel(logging.INFO)  #Show info messages for now
#...
logging.root.addHandler(_CONSOLE_OUT)

#...

def set_console_level(level):
    """Change the level at which console messages are printed"""
    assert _CONSOLE_OUT is not None #Set at root
    _CONSOLE_OUT.setLevel(level)