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]))
HTH!
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")
Or:
>>> 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)
Usage:
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.
精彩评论