5
\$\begingroup\$

I have the following code:

#!/usr/bin/env python3
import os, argparse

if __name__ == '__main__':
    # Parse arguments.
    parser = argparse.ArgumentParser()
    parser.add_argument("-v", "--verbose",  action="store_true", dest="verbose")
    args = parser.parse_args()

    try:
        verbose = bool(os.environ['VERBOSE'])
    except KeyError:
        verbose = args.verbose

    print("Verbose:", verbose)

And I would like to find the simpler way of returning value from two different sources (either system variable or parsed argument).

Ideally I would expect to find some one-liner such as:

verbose = bool(os.environ['VERBOSE']) or args.verbose

however instead I have KeyError exception, therefore I had to implement exception handler.

I'm expecting the following tests to print True (if verbose is set):

VERBOSE=1 ./test.py
./test.py -v

otherwise False.

\$\endgroup\$
6
\$\begingroup\$

Using get on the os.getenv dictionary and specifying args.verbose as the default value (2nd param of the .get call) will have your desired outcome:

import os
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-v", "--verbose",  action="store_true", dest="verbose")
    args = parser.parse_args()

    verbose = bool(os.environ.get('VERBOSE', args.verbose))

    print("Verbose:", verbose)

Test runs:

$ ./test.py -v; VERBOSE=1 ./test.py ; ./test.py
Verbose: True
Verbose: True
Verbose: False

Same output as your original.

Other notes:

  • The comment # Parse arguments. was pointless
  • Imports should appear on separate lines as per PEP8
\$\endgroup\$
  • 2
    \$\begingroup\$ Default val... good call. \$\endgroup\$ – rolfl May 2 '15 at 23:11
  • \$\begingroup\$ Where do I find documented os.environ.get()? I've tried here, but it doesn't mention anything about the get() syntax. Or it's just a standard method which can be used anywhere? Update: Ok, I've found it here. \$\endgroup\$ – kenorb May 3 '15 at 12:18
3
\$\begingroup\$

Note that Python raises a keyError whenever you access a dictionary key that is not defined. The way to avoid that error is to get() the key which will return None if the key was not set.

For the Environment in particular, there's the os.getenv(...) call which does essentially the same, but simpler.

As a result, your try/catch could just be:

verbose = args.verbose or bool(os.getenv('VERBOSE'))
\$\endgroup\$
  • 1
    \$\begingroup\$ That changes the meaning in the case where args.verbose is true and the environment variable VERBOSE is the empty string. \$\endgroup\$ – Gareth Rees May 3 '15 at 10:56
3
\$\begingroup\$

When VERBOSE=0, the following code:

bool(os.getenv('VERBOSE'))

still returns True.

An alternative solution would be:

bool(distutils.util.strtobool(os.getenv('VERBOSE')))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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