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