python 3: log function signature problem
I often write the following code:
print('object', 'moved', 'from =', object.location, 'dest =', new_location)
print('object', 'created', 'at =', object.location, 'status =', status)
and so on.
I was planning to replace all of these with a function log
:
def log(self, action, **details):
print('object', action, end = '')
for var, value in state.items():
print(var, '=', value, end = '')
print()
This almost works - except for two problems. First, I can't control the order of the output, and it's important to me. Of course, details
is just a dictionary, so the order of the parameters is lost. Second, I can't use any language keywords, e.g., from
as the name of the keyword argument.
Is there any solution that avoid unnecessary verbosity but doesn't suffer from these problems?
The reason I want to use log
function is that I may want to disable / enable it or change the format in a single location.
You know about the logging module, I take it?
I would just use preformed messages, and substitute the necessary bits in:
movedmsg = "object moved from = %s to = %s"
print(movedmsg % (object.location, new_location))
You might prefer the new style of string formatting:
movedmsg = "object moved from = {0} to = {1}"
print(movedmsg.format(object.location, new_location))
If you did need to do it with a dictionary-like structure, you could make an OrderedDict. But that is a bit more verbose. And it's not really the "one obvious way to do it".
The cleanest solution I can think of is to pass in a tuple of key/value pairs instead.
def log(action, *details):
print('object', action, end = '')
for var, value in details:
print(var, '=', value, end = '')
print()
log("moved", ("from", obj.location), ("dest", new_location))
You could write a function that captures a format string and returns another function that does the actual logging. That could be useful if you are going to be using a single format frequently.
def makelogger(*format):
def logger(action, *args):
print("object", action, format % args)
return logger
logger = makelogger("from = %s dest = %s")
logger("moved", obj.location, new_location)
# do a one-off
makelogger("from = %s dest = %s")("moved", obj.location, new_location)
Just some thoughts.
精彩评论