Syntax error when passing unpacked argument to print in Python

3.5k views Asked by At

Instead of a simple debug/log print as this:

print "error ", error_number

I would like to use a log function that I can expand when required looking something like this:

def log(condition, *message):
    if(<do something here...>):
        print(*message)
        <perhaps do something more...>

and call it like this:

log(condition, "error ", error_number)

But I get the following syntax error:

print *message
      ^ SyntaxError: invalid syntax

Is it a limitation of the print function or is there some way to make it work? If not, is there an equivalent to print that I could use?

I'm using Python 2.7 by the way...

4

There are 4 answers

0
wRAR On BEST ANSWER

print is not a function in Python 2.x. In the first snippet you are printing a tuple and the last one has invalid syntax. If you want to use the print function, you need to enable it via from __future__ import print_function.

1
themel On

You just use *args to declare the argument tuple, not to access it. See the example in the docs:

def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))

The fact that you get a SyntaxError should tip you off that this has nothing to do with print, anyway.

4
Joël On

You should use print message directly, that's enough (it will print the tuple of extra arguments).


Little addition to previous answers: in Python 2.x, print is not a function but a statement, but print(arg1, arg2) is valid... as using print statement on the tuple (arg1, arg2).

This is a bit different from print arg1, arg2 as one can see:

>>> print 'aaa', 'bbb'
aaa bbb
>>> print('aaa', 'bbb')
('aaa', 'bbb')

Now, in addition to themel's answer:

case 1: not using * to expand the argument tuple

>>> def p(*args):
...     a(args)  # <== args is a tuple
>>> def a(*args):
...     print args  # <== args is a tuple (but nothing else can be used)
>>> p('bb')
(('bb',),)

Result is a tuple of a tuple.

Case 2: expanding the arguments in p:

>>> def p(*args):
...      a(*args)  # <== now arguments are expanding
...
>>> p('bb')
('bb',)

Result is a tuple of arguments given to p.

So *args is correct use, but this is not allowed in a statement.

0
Oliver On

If you don't want to use __future__, you can define the logging function like this:

def log(condition, *message):
    if(<do something here...>):
        print ' '.join(str(a) for a in message)
        <perhaps do something more...>