Pythonic implementation of quiet / verbose flag for functions

3.7k views Asked by At

In an effort to write pythonic code, I wonder is there a style guide covering the use of quiet or verbose options for functions.

For example, in my Python package I have a range of functions which call each other, thus it is desirable for the user to be able to request a printed output at times.

For example:

def simple_addition(a, b, silent=True):
    res = a + b
    if not silent: print('The answer is %i' % res)
    return res

Is there a standard arg name here. e.g. Should "quiet" / "silent" be used to suppress all printed outputs. Or should "verbose" be used to demand this if True?

3

There are 3 answers

2
Dekel On BEST ANSWER

Basically you can use the logging module which gives you the ability to set the Level of logging you want, and the logger will save/print/export (based on your config) the logged values.

import logging
logging.warning('Watch out!')  # will print a message to the console
logging.info('I told you so')  # will not print anything

You can set the level of your logger using:

logging.basicConfig(level=logging.INFO)

And there are many more options there.

0
Sun Bee On

I have tended to go with:

def simple_addition(a, b, verbose=True):
    res = a + b
    print('The answer is %i' % res) if verbose else None 
    return res
0
Rudy Matela On

If you don't want to rely on a logging library, I think your solution is already pythonic enough. It may be a little bit more pythonic to write:

def simple_addition(a, b, silent=True):
    res = a + b
    if not silent:
        print('The answer is %i' % res)
    return res

As stated in PEP 8, Other Recommendations, single-line if statements are okay, but discouraged.

There are other possibilities.

Using or

Using the or operator to encode a condition is arguably not pythonic but personally I think it reads nice: "silent or...", "quiet or...". See below:

def simple_addition(a, b, silent=True):
    res = a + b
    silent or print('The answer is %i' % res)
    return res

The or operator does short-circuit, so print and its arguments are only evaluated when silent is False like when using an if statement.

A disadvantage is that mypy type checking will fail if silent is bound to a boolean type:

$ cat > add.py
def simple_addition(a, b, silent: bool = True):
    res = a + b
    silent or print('The answer is %i' % res)
    return res
^D
$ mypy add.py
add.py:3: error: "print" does not return a value

noop ternary

We could also do this:

def noop(*args, **kwargs):
    pass

def simple_addition(a, b, silent=True):
    _print = noop if silent else print
    res = a + b 
    _print('The answer is %i' % res)
    return res

...but it feels rather unpythonic.