Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

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

From Wikipedia, the free encyclopedia
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 ). 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: 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