Wikipedia:Reference desk/Archives/Computing/2019 November 14

Computing desk
< November 13 << Oct | November | Dec >> Current desk >
Welcome to the Wikipedia Computing Reference Desk Archives
The page you are currently viewing is a transcluded archive page. While you can leave answers for any questions shown below, please ask new questions on one of the current reference desk pages.


November 14

edit

Convert *args to a single string in Python 3

edit

Let's a say I have a thin wrapper around print() in Python 3:

def log(*values):
    print(*values)

# thousands of logging statements sprinkled throughout the app
log("one parameter")
log("multiple parameters", 1,2,"hello world", {3:4, 4:5}, [], None, set())

And now instead of printing directly to console, I want to log to a log file instead:

import logging

logging.basicConfig(filename='logfile.log', level=logging.INFO)

def log(*values):
    logging.info(*values)

# thousands of logging statements sprinkled throughout the app
log("one parameter")
log("multiple parameters", 1,2,"hello world", {3:4, 4:5}, [], None, set())

However since input format for print() differs from that of the logger's, the multiple parameter logging statement now throws an error.

Is there a way to convert the print() *args to a single string so that it can be fed into logger.info()? Mũeller (talk) 14:45, 14 November 2019 (UTC)[reply]

@Mũeller: May be this thread at StackOverflow will be of some use for you...?
python3 print to string
Once you get your output in a strig, pushing it further either to a file, to some logging interface or to GUI is easier. --CiaPan (talk) 15:26, 14 November 2019 (UTC)[reply]
  • One way would be ' '.join([str(arg) for arg in args]) (similar to what print does, and much simpler than the linked SO solution to a more complex question).
One could argue for ' '.join([repr(arg) for arg in args]) instead if you want to later parse the logs and recreate some objects (see [1]). I would argue that if you need to log anything else than strings and integers, "dump everything in a text file" is an approach too crude, but YMMV. TigraanClick here to contact me 15:47, 14 November 2019 (UTC)[reply]
Perfect! Thank you so much, you two! Much appreciated. Mũeller (talk) 00:51, 15 November 2019 (UTC)[reply]
  Resolved

I think you can use:

def log(*values):
    logging.info(values)

log("multiple parameters", 1,2,"hello world", {3:4, 4:5}, [], None, set()) # etc.

That is the log function receives all those args as a single tuple, and it passes the tuple to logging.info which handles formatting the tuple. That works in python 3.8 but I didn't check earlier python versions. 67.164.113.165 (talk) 17:24, 15 November 2019 (UTC)[reply]

That's a very cool feature. I didn't know that before. Though unfortunately in this case it adds extraneous brackets in the output (since it's passed in as a tuple, like you mentioned):
INFO:root:('multiple parameters', 1, 2, 'hello world', {3: 4, 4: 5}, [], None, set())
Also I slightly prefer " " instead of ", " as the separator, because I got used to writing
log("variable_x =", variable_x)

Mũeller (talk) 04:38, 16 November 2019 (UTC)[reply]

Python 3.8 has that built in:[2] log(f'{variable_x=}'). 67.164.113.165 (talk) 19:08, 16 November 2019 (UTC)[reply]

Very nice, thanks! Python gets better every year. Mũeller (talk) 04:32, 17 November 2019 (UTC)[reply]