'Python 3 operator >> to print to file
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?
Solution 1:[1]
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.
Solution 2:[2]
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.
Solution 3:[3]
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)
Solution 4:[4]
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("%s\n" % 'msg')
f.close()
Tested both scripts on Python 2.7.17 and 3.6.9.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | ncoghlan |
| Solution 4 | Alexander Samoylov |
