4

I'm using mod_wsgi and was wondering if it's possible to over-write the print() command (since it's useless).

Doing this doesn't work:

print = myPrintFunction

Since it's a syntax error. :(

Paolo Bergantino
  • 480,997
  • 81
  • 517
  • 436
Ian
  • 24,116
  • 22
  • 58
  • 96
  • Just for those new to Python and to reduce what might confuse new coders; the original poster mentions/ed a "print() command". Python has statements which can not be overridden. Python also has functions; some built in. Python does not have any "commands". However the syntax "someword()" or in this case "print()" tells other Pythoneers that "someword" is a function, not a statement, because of the "()" ending parenthesis. Functions, even built-in ones, can be overridden. This comment is only intended to clarify. – DevPlayer Apr 11 '12 at 13:26
  • Same question; more posts: http://stackoverflow.com/a/10106489/502519 – DevPlayer Apr 11 '12 at 13:28

5 Answers5

13

Print is not a function in Python 2.x, so this is not directly possible.

You can, however, override sys.stdout.

If you are on Python 3.0 in which print is now a function what you have would then work, assuming you have the right signature. Also see a related question in this site.

Community
  • 1
  • 1
Paolo Bergantino
  • 480,997
  • 81
  • 517
  • 436
6

Would

import sys
sys.stdout = MyFileWrapper()

or something similar work?

CAdaker
  • 14,385
  • 3
  • 30
  • 32
  • >> AttributeError: 'function' object has no attribute 'write' (when calling the replacement) :( – Ian Apr 21 '09 at 01:31
  • Cancel that, it works if the replacement object has a "write()" function. cool. :) – Ian Apr 21 '09 at 01:33
1

It is worth noting that use of 'print' to sys.stdout in Apache/mod_wsgi was deliberately restricted. This is because a portable WSGI application should not use either sys.stdin or sys.stdout as some WSGI implementations use them to communicate to the server.

Apache/mod_wsgi is therefore trying to force you to write your WSGI application such that it will be portable to other WSGI implementations.

Unfortunately, too many people seem not to care about writing good code and so mod_wsgi 3.0 will allow you to write to sys.stdout and thus use 'print' without redirecting output to 'sys.stderr' as you should be doing.

Either way, the mod_wsgi documentation details how to remove the restriction in versions of mod_wsgi prior to 3.0. In particular, see documentation about the WSGIRestrictStdout directive. The documentation about debugging techniques also talks about the issue and about mapping sys.stdout to sys.stderr.

You can read a commentary which summaries this issue at:

http://blog.dscpl.com.au/2009/04/wsgi-and-printing-to-standard-output.html

Graham Dumpleton
  • 57,726
  • 6
  • 119
  • 134
1

If you are using 3.0, print is a function. If you are using 2.6, you can from __future__ import print_function and continue with a print function.

If <= 2.5, you can replace stdout like others have suggested, but be very careful if your wsgi server will call your app in multiple threads simultaneously. You WILL end up with simultaneous requests being sent down the same pipe.

I haven't tested it, but you could try something like this:

import sys
import threading

class ThreadedStdout(object):
    def __init__(self):
        self.local = threading.local()
    def register(self, fh):
        self.local.fh = fh
    def write(self, stuff):
        self.local.fh.write(stuff)

sys.stdout = ThreadedStdout()

def app(environ, start):
    sys.stdout.register(environ['wsgi.stdout'])

    # Whatever.
Mike Boers
  • 6,665
  • 3
  • 31
  • 40
0

While you can redirect stdout to different sources like file for logging, as Paolo mentions, you probably wouldn't need it. I didn't need it. If you really needed to log stuff, you would be using logging itself in the first place, wouldn't you? Also, even when you don't print a thing, the third party libraries you use may do. Just redirect it and get going.

The simplest solution to this problem is to redirect all stdout into stderr. In the wsgi configuration file, just redirect as necessary.

sys.stdout = sys.stderr
lprsd
  • 84,407
  • 47
  • 135
  • 168