Tutorial :Writing a 'print' function in Python


I want to create a function that works like the build-in print function in Python:

print 'test', i, 'started'  

So a call like this should work:

log('test', i, 'started)  

The log function should call the logging.info() function (from the Python logging module). How can I create such a function?

This is my first try:

import logging  def log(*args):      logging.info(args)    log('test', i, 'started)  

But the output is not what I want:

('test', 2, 'started')  

While it should be:

test 2 started  


This works:

def log(*args):      logging.info(' '.join(map(str, args)))  


You can do this kind of thing:

def log(*args):    logging.info(' '.join(args))  


How about:

def log(*args):      logging.info(' '.join([str(arg) for arg in args]))  



Define a function that takes a variable number of arguments, you can operate on the parameter list args to print it how you'd like:

>>> def log(*args):  ...   print args    >>> log("a", 1, "b")  ("a", 1, "b")  


>>> def log(*args):  ...   for a in args:  # <- loop over the arguments  ...     print a,   # <- notice the comma that says "no newline".  ...   print        # <- force a newline after the log statement.    >>> log("a", 1, "b")  a 1 b  

If you want to use logging.info:

logging.info(msg[, *args[, **kwargs]])

Logs a message with level INFO on the root logger. The arguments are interpreted as for debug().

>>> def log(*args):  ...   logging.info(" ".join("%s" %a for a in args))  


I do this, to make it accept a format string. Coming from a C world, I like my format strings. I use code exactly like this in several production systems.

def logf(fmt, *args):      try: m = fmt % args      except:          # Catch mismatch between fmt/args; prevents logging.info from          # failing below, as well.          m = fmt          fmt = "%s"      if DEBUG:          stderr.write("[%s] %s\n" % (time.asctime(), m))      logging.info(fmt, *args)  


logf("There are %u entries in the list, and my mood is %s.", len(L), "sad")  logf("It works without arguments, as well")  logf("Test %d started", i)  

Call me old-school, I guess. This is all Python 2, by the way - 3 is far different.


The logging methods require a format-string as the first argument (or, as some others have suggested, a literal string to log). You can easily generate a format string for a given-number of arguments with code something like this:

def log(*args):      fmt_string = ' '.join(['%s'] * len(args))      logging.info(fmt_string, *args)  

This works because the multiplication operator on lists is defined to extend the list with copies of the list's contents.

Note that I'm passing *args as the second "argument" to logging.info -- this is Python's syntax for expanding a sequence (args will be a tuple, I believe) into a series of positional arguments in the function call.


One day I was reading the python docs and I came across the functools.partial() method (or I read about it somewhere -- I can't remember). A little playing around led to the following code I now put at the beginning of every python script I write:

  import sys, functools    nl = "\n"    def StreamOut(stream, *s, **kw):      k = kw.setdefault      # Process keyword arguments      sep     = k("sep", "")      auto_nl = k("auto_nl", True)      prefix  = k("prefix", "")      convert = k("convert", str)      # Convert position arguments to strings      strings = map(convert, s)      # Dump them to the stream      stream.write(prefix + sep.join(strings))      # Add a newline if desired      if auto_nl:          stream.write(nl)    out  = functools.partial(StreamOut, sys.stdout)  outs = functools.partial(StreamOut, sys.stdout, sep=" ")  dbg  = functools.partial(StreamOut, sys.stdout, sep=" ", prefix="+ ")  err  = functools.partial(StreamOut, sys.stderr)    out("Hi there", "how are you?")  outs("Hi there", "how are you?")  

Put it into a file and try them out. This makes for some easily-extendible functions.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »