5

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...

hobb
  • 166
  • 1
  • 10
  • I added the way to modify your script, without using `__future__` module; see my answer. – Joël Nov 09 '11 at 09:25

4 Answers4

9

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.

wRAR
  • 25,009
  • 4
  • 84
  • 97
7

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...>
John Y
  • 14,123
  • 2
  • 48
  • 72
Oliver
  • 27,510
  • 9
  • 72
  • 103
3

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.

Joël
  • 2,723
  • 18
  • 36
  • 1
    Good info that the main issue here is that _print_ is a statement (a funky one), and that statements do not support unpacked arguments (even when they are funky variable argument accepting statements) – hobb Nov 09 '11 at 09:47
  • using `print message` directly prints the tuple as "('error ', 22)" instead of "error 22". Tried that before posting, but its not what I wanted. – hobb Nov 09 '11 at 09:54
  • Then, question: was your code `print("error ", error_number)` doing what you expect? I would say no, as `print ('error ', 3)` prints `('error ', 3)` and not `error 3` directly. So that's correct, you needed the new version of print. – Joël Nov 09 '11 at 10:00
  • My bad, I originally had a lot of `print "error", 3`-like lines in my code (printing what I expected). When I tried to get the log method to work I tried a lot of different syntaxes and the one with parenthesis happened to end up in the question. Q updated. – hobb Nov 09 '11 at 11:52
-2

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.

themel
  • 8,825
  • 2
  • 32
  • 31
  • @themel No, this is wrong, see my answer: if you do not expand, you get a tuple; if you expand, you get several arguments. This is allowed anywhere. Anyway, your example is correct, as in this case, you need to use the tuple. – Joël Nov 09 '11 at 08:38