1

I'm trying to change Python 2.7 code such that it can run both on 2.7 and 3.6 The obvious problem is print. It's called without parenthesis in 2.7 and with parenthesis in 3.6 So I tried runtime version detection (detection code taken from this answer):

def customPrint(line):
    if sys.version_info[0] < 3:
        print "%s" % line
    else:
        print( line )

and when I run this under Python 3.6 I get an error message saying

SyntaxError: Missing parenthesis in call to 'print'

So clearly Python tries to interpret all the code. That's different from PHP.

How do I have such custom implementation of print that it uses either print from Python 2 or from Python 3 depending on where it runs?

sharptooth
  • 167,383
  • 100
  • 513
  • 979

3 Answers3

3

print is a keyword in python2.7, and it will accept a tuple as the next piece of syntax, making it look like a function call:

Python 2.7.3 (default, Jun 21 2016, 18:38:19) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'hi'
hi
>>> print("hi")
hi

This can be misleading if you use a tuple of strings, for example:

>>> print("hello", "world")
('hello', 'world')

The best thing to do is use an import to tell the intepreter to replace the keyword with the function call: from __future__ import print_function

>>> from __future__ import print_function
>>> print("hi!")
hi!
>>> print "hi"
  File "<stdin>", line 1
    print "hi"
             ^
SyntaxError: invalid syntax
>>> print("hello", "world")
hello world
thaavik
  • 3,257
  • 2
  • 18
  • 25
  • I'd argue that importing `print_function` is the _only_ way to ensure compatibility for both. – erip Aug 02 '17 at 15:41
  • 1
    Negative. In python2, `print` is a statement, and never a function. `print("hi")` evaluates as `print ("hi")`. The parentheses serve no purpose in that statement. You will see this if you tried `print("Hello", "world"), which prints out a tuple, rather than a string – inspectorG4dget Aug 02 '17 at 15:42
  • Second that, does not work. Try here: http://interactivepython.org/runestone/static/pip/StringFormatting/interpolation.html – Joe Aug 02 '17 at 15:47
  • Yes, you're right. That distinction is important, and it makes the future import even more important. I'll update my answer. – thaavik Aug 02 '17 at 15:47
1

You have the right idea in thinking about versioning. However, python isn't interpreted in the way you think. The code is first compiled into bytecode, which is then run (unlike PERL). This is why you can't write an infinite while loop and edit it in real time and expect it to change the output you see.

Therefore, your syntax still has to be python3-compliant, even in the python2 sections of code.

One way to fix this is to import print_function from __future__. To do that, add the following line to the top of your python script:

if sys.version_info[0] < 3:
    from __future__ import print_function

... and then just use python3's print(...) even in the python2 sections of your code

inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
0

You can conditionally from __future__ import print_function when you detect Python 2.*.

if sys.version_info[0] < 3:
    from __future__ import print_function
Sumner Evans
  • 8,951
  • 5
  • 30
  • 47