1

I write CLI-executable Python 3 scripts regularly to do data compilation and some maintenance tasks, and try to adhere to PEP 8 and the Google Python Style Guide when doing so. Google's guide says to avoid using global variables, while PEP 8 offers naming conventions but doesn't really encourage or discourage use of them, so I don't use them.

However, I've lately found myself using a "verbose" option/switch a lot along with a "printv" function to use while debugging. It usually looks like this:

def printv(opts, msg, **kwargs):
    if opts.verbose: print(msg, **kwargs)

As incredibly lazy as I am, I'd like to make it so I don't need to pass the opts argument (which is an OptionParser object) to printv. The simplest method would be to use a global variable, sure. Another thought I had would be to set a "VERBOSE" variable in os.environ, since the switch is, conceptually, making a change to the execution environment. Obviously it's counter-intuitive, but is it pythonic?

4
  • 2
    I'd just say that it's never right to fiddle with environment variables to store internal program state. Dec 16, 2013 at 15:54
  • 2
    might want to consider using logging module in your app. That way when you initialize logger when the app starts, you can look at the option and select between two logging levels (e.g. "logging.WARN" vs. "logging.INFO"). That way you won't have to sprinkle if-statements all over your code.
    – DXM
    Dec 16, 2013 at 16:29
  • @DXM: I just read up on the logging module and I can't believe I hadn't noticed it before. Just what the doctor ordered, and I'm loving how it can be configured, especially in how it can output to both the terminal and a file in one call, with each destination able to have its own independent settings for format and level.
    – p0lar_bear
    Dec 16, 2013 at 17:21
  • @DXM: maybe you should change your comment into an answer? I guess the OP will be happy to accept it.
    – Doc Brown
    Dec 16, 2013 at 17:30

2 Answers 2

2

IMHO the level of visibility where you grab your options from should typically match the level of visibility of your printv function. So when there is just one global printv function visible everywhere in your program, it is ok to have the "verbose option" also visible globally. If your printv is instead a class member (for example, of a "Logger" class, see comment from DXM), the "verbose option" should be a member of the same class. If it is a function within a module - same rule. This feels somewhat natural to me, however I hardly believe that this is a python specific idiom.

Using an environment variable is appropriate for controlling the "verbose option" from outside the program, this makes no sense if the "verbose state" is only switched on and off inside your program. If you need this (for example, because you have two or more programs which shall be controlled by the same VERBOSE environment variable), read the environment once after the program start and store the state in your internal globalOpts.verbose variable (for later usage, for example, in your printv function).

0

Storing program state in the environment is not Pythonic.

Looking at the GPSG section on Global Variables it says explicitly that one of the exceptions includes default options for scripts; I would say if your CLI is a single file script, then having your opts object be global is just fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.