1

Ran into some interesting Python behavior today. I though I was writing

print("{}".format("some value")) 

but instead I wrote

print("{}").format("some value")

and funnily enough it worked. So my question is, how does this work?

Digging deeper

This behavior seems to be python2 specific.

Python2.7

>>> print("{}").format("testing")
testing

Python3.4

>>> print("{}").format("testing)
  File "<stdin>", line 1
    print("{}").format("testing)
                               ^
SyntaxError: EOL while scanning string literal

It also seems like the print function of python2 doesn't have a return value but Python3 does? so that confuses me even more.

Python2.7

>>> type(print("testing))
  File "<stdin>", line 1
    type(print("testing))
             ^
SyntaxError: invalid syntax
>>> a = print("testing")
  File "<stdin>", line 1
    a = print("testing")
            ^
SyntaxError: invalid syntax

Python3.4

>>> type(print("{}"))
{}
<class 'NoneType'>
>>> a = print("{}")
{}
>>> a
>>> type(a)
<class 'NoneType'>
AlexLordThorsen
  • 8,057
  • 5
  • 48
  • 103
  • As a side note (unrelated to the parentheses issue), you probably shouldn't be doing `"{}".format(something)`. This is usually going to be identical to `str(something)`, and even that is unnecessary if you're passing the result to `print`, (which will call `str` on its arguments for you). – Blckknght Aug 19 '15 at 02:58
  • You're missing some fundamental information about `print` (check the suggested [related question](http://stackoverflow.com/questions/826948/syntax-error-on-print-with-python-3?rq=1) in the sidebar), and some of your strings aren't terminated. – TigerhawkT3 Aug 19 '15 at 03:06
  • possible duplicate of [Syntax error on print with Python 3](http://stackoverflow.com/questions/826948/syntax-error-on-print-with-python-3) – TigerhawkT3 Aug 19 '15 at 03:30

4 Answers4

8

In Python 2, print is a statement, not a function (unless you do from __future__ import print_function at the top of your module). This means that the parentheses around the thing you're printing are not part of a function call, but just treated as grouping parentheses. In the situation you describe ("{}") is the same as "{}" (the parens do nothing), so the format call works just like you'd expect if you wrote "{}".format(...).

In Python 3, print is a function, so the parentheses are not optional and can't be put in the wrong place. print returns None, so you're almost certainly going to get an error if you do print(something).something_else, since None doesn't have a something_else attribute.

Blckknght
  • 100,903
  • 11
  • 120
  • 169
1

In Python 2.7, print is a statement; this means that

print("{}").format("testing")

prints one expression, the result of the expression ("{}").format("testing"). That is, the format method is called on the (parenthesized) string before the print statement is evaluated. If you use

from __future__ import print_function

in the 2.7 examples, you'll get identical behavior to Python 3.

chepner
  • 497,756
  • 71
  • 530
  • 681
1
  1. You're missing the closing quote after some strings (e.g. "testing).
  2. As others are saying, Python 2 doesn't have a print() function, it has a print statement. Your strings (even if they were properly closed) are not what and where you think they are.
TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
0

In Python 2, print is a statement keyword like raise, not a function. Parentheses aren't used for its arguments, and so print("{}").format("testing") is parsed as though you'd written print ("{}").format("testing"), which is the same as print(("{}").format("testing")). Because print is a statement, it cannot be used as an expression, and therefore it cannot have a return value.

If you want print in Python 2 to act like Python 3's print function, place this line at the top of your file:

from __future__ import print_function
jwodder
  • 54,758
  • 12
  • 108
  • 124
  • It's worth noting that `yield` is now an expression, not a statement in recent versions of Python 3 (you can do `foo = yield bar`). – Blckknght Aug 19 '15 at 02:55
  • @Blckknght: `foo = yield bar` also works in Python 2. See https://docs.python.org/2/reference/expressions.html#yieldexpr – PM 2Ring Aug 19 '15 at 05:25
  • @PM2Ring: Ah, I'd forgotten when that feature was added. – Blckknght Aug 19 '15 at 05:46