Pylint - "Using the global statement"

12,810

Solution 1

You could create it at import time:

_console_out = ConsoleHandler()

where ConsoleHandler is a factory function or your class that create and setup the handler.

Solution 2

This is a weird pattern to set items outside of the methods scope. It will lead to problems later because you won't know where global variables are being set from.

Your code is also relying on the order of execution of methods to set variables that - presumably - other parts of your code rely on. This may cause problems later if you forget to call an init() especially when importing things (of course you could always stick it in __init__.py, but that's not the point here).

Given those, I think another way around is to create a class and set the variable inside the class (giving it another namespace); or if you want to keep it as is, as Sebastian suggested return the configuration variables.

You can return a tuple and then unpack it to create your global variables if you need to set more than one.

>>> def foo():
...   return "hello","world"
...
>>> a,b = foo()
Share:
12,810
Retsam
Author by

Retsam

Updated on June 04, 2022

Comments

  • Retsam
    Retsam almost 2 years

    I'm trying to work on my current python program being very conscious of pylint warnings, so while I realize I can simply turn off the warning, I want to be sure that there is not a more desirable solution before I do.

    My current section of the code is my logging code. I have a function init() that sets up handlers and attaches them to the root logger, and a function set_console_level(level) that sets the level at which console messages are reported (DEBUG, INFO, etc..):

    _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) 
    

    As far as I could tell from my reading, this is the way to do this. The line global _CONSOLE_OUT is needed in order to write to the module-level variable. However, when I run pylint on this file I get the warning W: 15,4:init: Using the global statement. Is there a way to avoid this warning? A better way to approach this problem?

    (Please don't say global _CONSOLE_OUT #pylint: disable=W**** without giving justification)

  • jfs
    jfs over 11 years
    @Retsam: You could refactor the part that creates handler into a separate function. It is a common idiom to initialize a singleton object at import time e.g., json, logging (root logger), random modules use it. I've updated the code.
  • Retsam
    Retsam over 11 years
    Ah. It would be good to clarify in the answer that ConsoleHandler() is a function that I would write, and not just the wrong name for the existing object constructor as I took it to be.