Redefining Python Print Operator Newline Generation Behavior

I have a bunch of legacy code to encode raw emails containing many print statements such as

print >>f, "Content-Type: text/plain" 

This is good and useful for emails, but now we use the same code to output the HTTP request. The problem is that the Python print statement prints '\n' , while HTTP requires '\r\n' .

It looks like Python (at least 2.6.4) generates the final byte code PRINT_NEWLINE for the print statement, which is implemented as

 ceval.c:1582: err = PyFile_WriteString("\n", w); 

Thus, there is no easy way to override the default print behavior for a new line. I reviewed the following solutions

After recording the output, simply do .replace('\n', '\r\n') . This will interfere with HTTP messages using multiple encoding. Create a wrapper around the target file object and the .write
 def write(self, data): if data == '\n': data = '\r\n' return self._file.write(data) 

Write a regular expression that translates print >>f, text to f.write(text + line_end) , where line_end can be '\n' or '\r\n' .

I believe that the third option will be the most suitable. It would be interesting to hear what your approach to the Python problem will be.

+7
python cpython printing
source share
6 answers

You must solve your problem now and forever by defining a new output function. Functions were printed, it would be much easier.

I suggest writing a new output function, the greatest possible fake of as much of the modern signature of the print function as possible (since using a good interface is good), for example:

 def output(*items, end="\n", file=sys.stdout): pass 

Once you have replaced all the fingerprints in question, you no longer have this problem - you can always change the behavior of your function! This is the big reason printing was done in Python 3, because in Python 2.x, β€œall” projects invariably go through the stage where all print statements are no longer flexible and there is no easy way out.

+10
source share

(You do not know how to do this if it is suitable for the shell that you are going to use, but in case ...)

In Python 2.6 (and many previous versions), you can suppress a new line by adding a comma at the end of the print statement, as in:

 data = 'some msg\r\n' print data, # note the comma 

The downside of using this approach is that the syntax and print behavior change in Python3.

+8
source share

In python2.x, I think you can do:

 print >>f "some msg\r\n", 

to break the ending new line.

In python3.x, this is much simpler:

 print("some msg", end = "\r\n", file = f) 
+4
source share

I think I would define a new writeline function in the inherited file / stream class and writeline code to use writeline instead of print . The file object itself may contain the line ending style as a member. This should give you some flexibility in behavior, and also make the code a little clearer, i.e. f.writeline(text) , unlike f.write(text+line_end) .

0
source share

I also prefer your third solution, but no need to use f.write, any user-written function / called. Thus, the following changes will become easy. If you use an object, you can even hide the target file inside it, thereby removing some syntax noise, such as a file or a newline.

Too bad print is a statement in python 2.x, while python 3.x print can simply be overloaded with something user-defined.

0
source share

Python has modules for both email processing and http headers in a simple way. I suggest you use them instead of solving problems that have already been resolved.

0
source share

All Articles