Python 3 operator >> to print to file

Question:

I have the following Python code to write dependency files of a project. It works fine with Python 2.x, but while testing it with Python 3 it reports an error.

depend = None
if not nmake:
    depend = open(".depend", "a")
dependmak = open(".depend.mak", "a")
depend = open(".depend", "a")
print >>depend, s,

Here is the error:

Traceback (most recent call last):
  File "../../../../config/makedepend.py", line 121, in <module>
    print >>depend, s,
    TypeError: unsupported operand type(s) for >>:
      'builtin_function_or_method' and '_io.TextIOWrapper'

What is the best way to get this working with Python 2.x and 3.x?

Asked By: José

||

Answers:

print() is a function in Python 3.

Change your code to print(s, end="", file=depend), or let the 2to3 tool do it for you.

Answered By: Amber

In Python 3 the print statement has become a function. The new syntax looks like this:

print(s, end="", file=depend)

This breaking change in Python 3 means that it is not possible to use the same code in Python 2 and 3 when writing to a file using the print statement/function. One possible option would be to use depend.write(s) instead of print.

Update: J.F. Sebastian correctly points out that you can use from __future__ import print_function in your Python 2 code to enable the Python 3 syntax. That would be an excellent way to use the same code across different Python versions.

Answered By: David Heffernan

Note that starting in Python 3.6.3 (September 2017), the error message for this case will be changing to recommend the Python 3 spelling:

>>> print >> sys.stderr
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for >>:
    'builtin_function_or_method' and '_io.TextIOWrapper'.
    Did you mean "print(<message>, file=<output_stream>)"?

(Explicit line breaks added to avoid side-scrolling – the actual error message just wraps at the width of your terminal window)

Answered By: ncoghlan

I can propose at least two ways.

1 – if-else way with eval() trick (works with stdout as well as with a file).

import sys
def println(s, f=sys.stdout):
    if sys.version_info[0] < 3:
        print >>f, s
    else:
        func = eval('print')
        func(s, end='n', file=f)

f = open('file.txt', 'a')
println('msg') # print to stdout
println('msg', f) # print to file
f.close()

2 – Use write() instead of print().

f = open('file.txt', 'a')
f.write("%sn" % 'msg')
f.close()

Tested both scripts on Python 2.7.17 and 3.6.9.

Answered By: Alexander Samoylov
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.