Python - Overridding print()

纵饮孤独 提交于 2019-12-05 17:43:41
Paolo Bergantino

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.

Would

import sys
sys.stdout = MyFileWrapper()

or something similar work?

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.

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

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!