Simple Output Buffering in Python

Recently, I needed a quick and simple solution to buffer output of a few Python scripts. When I went to look for a module, I was astonished to find that one didn't exist. I quickly decided to change this. In this article, we'll discuss simple ways to buffer output using StringIO and I'll introduce my output buffering module that I constructed.

Why Buffer Output?

Good question. It's different for everybody. For me, I needed it so that I could allow plugins to be built that could seamlessly print output and have my plugin manager be able to capture and parse the data rather than immediately printing it to stdout. Other cases include situations where one would want to gzip all output or implement a "just-in-time" word filter.

Possible Solutions

The way that I see output buffering implemented most often by others is through replacing sys.stdout with an instance of a class which has a write method. This works for some cases, but what many forget is that stdout is considered a file, and thus has the same methods available as a file does. So, implementing only the write method will work for few cases, but can and will break code in other places. It's best to never even consider this as a solution. I just mention it so people using it will realize that they're using a weak solution.

The quickest solution to get around this is to use an instance of the StringIO class as a replacement for sys.stdout, but even this has its limitations. For instance, automatic function callbacks and automatic stdout replacement are out of the question.

The best solution is to use something like my output buffering module. It provides a very robust OutputBuffer object that can suit most needs.

The Quick Solution (using StringIO)

Using StringIO may not be a very robust choice, but it gets the job done when you need to hack something together really quickly.

import StringIO
import sys
 
old_stdout = sys.stdout  # Need to save it for later
sys.stdout = StringIO.StringIO()  # Replace stdout with StringIO instance
 
print "Hello, world!"  # Will not print. Is instead saved to the buffer.
 
data = sys.stdout.getvalue()  # Retrieve the buffered data.
sys.stdout = old_stdout  # Set stdout to the real one. ( stops buffering )

There are a number of problems to doing output buffering this way. Most notably, you have to keep a pointer to the original stdout instance the entire time, otherwise you're not able to print ever again for the entire script. Yeah, that's a pretty big deal.

The Robust Solution (using the ob module)

The following solution uses a module that I built myself. (Available here)

import ob
buf = ob.OutputBuffer()
buf.start()  # Begin output buffering.
 
print "Hello, world!"  # Will not print. Is instead saved to the buffer.
 
buf.stop()  # Stop output buffering.
data = buf.getvalue()  # Retrieve the buffered data

Now, using the ob module has a number of improvements over simply using StringIO. Most notably, it allows you to never have to directly manipulate sys.stdout - it does everything for you. Additionally, if you lose a reference to your OutputBuffer object, not to worry; the ob module provides a way of getting the buffer object:

import ob
buf = ob.get_top()  # Retrieve the top-most buffer.

At that point, you can again work with the OutputBuffer instance without ever having to directly touch sys.stdout or perform any tests. I'd suggest going to the output buffering module page and reading up on what else it can provide you.

Final Thoughts

Output buffering is a powerful tool. I'm incredibly surprised that Python didn't already provide a solution to it, but at the same time I'm a bit glad because it allowed me to get creative and build my own solution. If you're going to do output buffering, don't be lazy. At the very least use the StringIO solution, but if you want to do it right, then use the ob module or something equivalent.

 

 

One Comment

  1. Jorge Vargas wrote,

    Hi,

    I just stumble upon this very same problem, and I find your class excellent as it solves exactly what I'm trying to do.

    Just one minor correction to this article. sys.__stdout__ , etc. Will keep the reference to the original stdout, similar variables exists for the other streams.

    So you don't really lose those references and you can replace them afterwards.

    Another unhappy thing is that your module is GPL3 which prevents me from using it in this particular codebase therefore I'm afraid I'm going to have to just learn from it :(

    Anyway great find and thank you.

Leave a comment

Take Albuterol Cheap
Inhaler Buying Albuterol
Drug Buying Albuterol
Order Cheapest Albuterol
Order Albuterol Free Delivery
Buying Without Prescription Aldactone
Buy Generic Aldactone
Order Aldactone Next Day Delivery
Purchase Aldactone Online no Prescription
Buy Tablets Aldactone
Take no Prescription Allopurinol
Purchase Allopurinol Drug
When to Take Allopurinol
Order Allopurinol Free Delivery
Pills Buying Allopurinol
Drug Buying Anafranil
Alternative Purchase Anafranil
Purchase Anafranil Drug
Buy Tablets Anafranil Online
Order no Prescription Anafranil
Pills Buying Atarax
Cheapest Order Atarax
Buying Without a Prescription Atarax Online
Buy Atarax Medication
Atarax 50
Avodart Finasteride
Take Avodart Legally
Purchase Avodart by Phone
Tablets Purchase Avodart
Why Take Avodart
Order Bactrim Generic
Buy Without a Prescription Bactrim
Take Bactrim Next Day Delivery
Buying Bactrim Overnight Delivery
Take Bactrim Medication
Why Take Celecoxib
Order Celecoxib Free Delivery
Order Celecoxib Next Day Delivery
Buy Cheap Celecoxib
Purchase no Prescription Celecoxib
Cheapest Buying Cipro
Order Cipro Free Delivery
Buy Without a Prescription Cipro
Buy Cipro Tablets
Purchase Cipro Free Delivery
Order Clomid Serophene Without a Prescription
Order Clomid Serophene Medication
Online Order Clomid Serophene Without Prescription
Buy Clomid Serophene Medication
Purchase Cheap Clomid Serophene
Buy Dapsone Without a Prescription
Alternative Order Dapsone
Buy Dapsone by Phone
Buy Dapsone Overnight Delivery
Buy Dapsone Tablets
Buy Desyrel Online no Prescription
Purchase Desyrel Next Day Delivery
Order Desyrel Free Delivery
Buy Desyrel Next Day Delivery
Purchase Cheapest Desyrel
Take Diflucan Medication
Purchase Diflucan Free Delivery
Tablets Buying Diflucan
Buy Diflucan Pills
Order Cheap Diflucan
Alternative Purchase Dilantin
Buying Without a Prescription Dilantin Online
Buy no Prescription Dilantin Online
Purchase no Prescription Dilantin
Cheapest Order Dilantin
Buy Tablets Diovan
Buy Diovan Free Delivery
Purchase Diovan Generic
Buying Pills Diovan
Buying Without a Prescription Diovan Online
Generic Order Doxycycline
Buy Tablets Doxycycline
Buy Doxycycline Overnight Delivery
Buy Tablets Doxycycline Online
Purchase Pills Doxycycline
Drug Order Elavil
Buy Elavil Overnight Delivery
Buy Elavil Without a Prescription
Take Elavil Legally
Buy Alternative Elavil
Purchase Online Without a Prescription Erythromycin
Purchase Erythromycin Without a Prescription
Generic Order Erythromycin
Pills Buying Erythromycin
Purchase Cheapest Erythromycin
Take Estrace Free Delivery
Pills Buying Estrace
Generic Buying Estrace
Purchase Online no Prescription Estrace
Order Estrace by Phone
Buy Furosemide Medication
Generic Buying Furosemide
Buying Furosemide On-Line
Buy Without a Prescription Furosemide
Take Furosemide Drug
Take Glucophage Next Day Delivery
Tablets Purchase Glucophage
Order Pills Glucophage
Order Glucophage Generic
Order Cheapest Glucophage
Purchase Imitrex Online no Prescription
Take Imitrex Without Prescription
Order Imitrex Medication
Buy Cheap Imitrex
Online Order Imitrex Without Prescription
Buy no Prescription Inderal
Pills Buying Inderal
Order Inderal Without a Prescription
Buying Inderal On-Line
Order Inderal Medication
Lasix 40
Buying Lasix On-Line
Buy Lasix no Prescription
Order Online Without a Prescription Lasix
Buy Lasix Generic
Take Levaquin Drug
Order Levaquin Pills
Buy Tablets Levaquin
Buying Without Prescription Levaquin
Purchase Cheapest Levaquin
Take Lexapro Daily Dose
Order Pills Lexapro
Take Lexapro Legally
Take Lexapro Drug
Purchase Generic Lexapro
Order Lipitor COD
Buy Pills Lipitor
Purchase Online Without a Prescription Lipitor
Lipitor Lipidor
Buy Cheapest Lipitor
Purchase Generic Lisinopril
Buy Lisinopril Tablets
Generic Buying Lisinopril
Purchase Lisinopril Online Without Prescription
Purchase Lisinopril Medication
Purchase Methotrexate Medication
Take Methotrexate Pills
Order Methotrexate Generic
Order Methotrexate Without a Prescription
Buy Tablets Methotrexate Online
Order Nizoral Pills
Order Nizoral Free Delivery
Order Nizoral no Prescription
Pills Buying Nizoral
Buy no Prescription Nizoral Online
Buy Nolvadex Cheapest
Alternative Order Nolvadex
Buying Nolvadex Free Delivery
Purchase Nolvadex COD
Alternative Purchase Nolvadex
Online Order Nortriptyline Without Prescription
Buying Without Prescription Nortriptyline
Purchase no Prescription Nortriptyline
Purchase Nortriptyline Online Without Prescription
Purchase Nortriptyline by Phone
Alternative Purchase Ortho Tri-Cyclen
Buy Ortho Tri-Cyclen Medication
Buying Ortho Tri-Cyclen Next Day Delivery
Online Buy Ortho Tri-Cyclen Without a Prescription
Purchase Ortho Tri-Cyclen Generic
Buy Tablets Premarin
Order Premarin Generic
Order Premarin Free Delivery
Purchase Pills Premarin
Purchase Premarin Next Day Delivery
When to Take Proscar
Order Proscar Free Delivery
Take Proscar Free Delivery
Cheapest Buy Proscar
Purchase Proscar Next Day Delivery
Online Order Risperdal Without Prescription
Buy Risperdal Without a Prescription
Generic Order Risperdal
Buying Risperdal Next Day Delivery
Buy Online Without a Prescription Risperdal
Buying Synthroid Without Prescription
Alternative Buying Synthroid
Order Synthroid by Phone
Buy Alternative Synthroid
Buy Online Without a Prescription Synthroid
Order Topamax Pills
Tablets Order Topamax
Order Cheap Topamax
Order Topamax Generic
Take Topamax Daily Dose
Purchase Valtrex COD
Buy no Prescription Valtrex
Buy Pills Valtrex Online
Tablets Buy Valtrex
Buy Valtrex COD
Legally Order Zithromax
Tablets Order Zithromax
Buy Without a Prescription Zithromax
Buying Without a Prescription Zithromax Online
Purchase Zithromax Without a Prescription