0

I saw the following SO posts on variable arguments in Python:

What does ** (double star) and * (star) do for parameters?
function call with named/unnamed and variable arguments in python
Can a variable number of arguments be passed to a function?

None of them answered my question. So, here it goes:

I would like to define couple of functions:

def LogError(log_file, *args):
  print("USER ERROR:", ***NOT SURE ABOUT THIS PART***, file=log_file)

def LogWarning(log_file, *args):
  print("USER WARNING:", ***NOT SURE ABOUT THIS PART***, file=log_file)

I want to call them using:

error_file = open("somefile")
LogError(error_file, "Unable to find", username, "in the database.")

warning_file = open("somefile")
LogWarning(warning_file, arg1, arg2, arg3)

I want the call to LogError to be the equivalent of

print("USER ERROR:", "Unable to find", username, "in the database.", file=error_file)

and I want the call to LogWarning to be the equivalent of

print("USER WARNING:", arg1, arg2, arg3, file=warning_file)

What's the best way to accomplish that?

Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    Since there are no other arguments to the call, `print("USER ERROR:", *args, file=log_file)`? (assuming Python 3) – Jeff Mercado Jul 30 '15 at 22:41
  • @JeffMercado, I tried that. That is equivalent of `print("USER ERROR:", ["Unable to find", username, "in the database."], file=error_file)`. – R Sahu Jul 30 '15 at 22:44
  • The `*` is important. It will expand `args` as if the function was called with the items as individual arguments in their corresponding positions. – Jeff Mercado Jul 30 '15 at 22:46
  • To get that `list` as an argument, you would have to do `print("USER ERROR:", list(args), file=error_file)`. I'm not sure what you're doing for `print("USER ERROR:", *args, file=error_file)` not to work, but I can't reproduce it. – TigerhawkT3 Jul 30 '15 at 22:47

2 Answers2

2

The first link you have should provide the answer

def LogError(log_file, *args):
  print("USER ERROR:", *args, file=log_file)

def LogWarning(log_file, *args):
  print("USER WARNING:", *args, file=log_file)

That would expand the arguments as you want. But instead of crafting your own solution, you should take a look at python's built in logging feature instead.

Anonymous
  • 11,740
  • 3
  • 40
  • 50
  • I must've done something strange while testing. I thought I had tried that and it didn't seem to work. It works now :) – R Sahu Jul 30 '15 at 22:53
0

Just join them with a space, since that's the end result anyway:

print('USER ERROR: {}'.format(' '.join(*args)), file=error_file)

You really should be using the logging module, which will make your life easier:

import logging

# Create a logger
log = logging.getLogger(__file__)

# Set the output for different log levels
# this is optional, you can write out all errors to the
# console and do many combinations, such as sending emails

warning_logger = logging.FileHandler('warnings.log')
warning_logger.setLevel(logging.WARNING)

error_logger = logging.FileHandler('error.log')
error_logger.setLevel(logging.ERROR)

# Set the format of messages
# levelname will be WARNING or ERROR depending on the message
log_format = logging.Formatter('USER %(levelname)s: %(message)s')

# Set the formatters for the error loggers
warning_logger.setFormatter(log_format)
error_logger.setFormatter(log_format)

# Add the handlers to the master logger instance
log.addHandler(warning_logger)
log.addHandler(error_logger)

# Now all you need is

log.warn('This is a warning')
log.error('This is a error')

For more details check out the logging module documentation and for more recipes, the logging module cookbook is worth a read.

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284