Reputation: 4561
From How to override python builtins with an import statement I obtained the following code:
from __future__ import print_function
def print(*args, **kwargs):
.
. some intervening logic
.
return __builtins__.print(*args, **kwargs)
This code works fine, but has module scope. That is, if there are print statements within this file they work as expected, going through the print() function as defined. However, importing it (from foo import *) has no effect within the module that imported it.
If I want to override the print function "globally" how is this best done. Ideally:
from MyOverrides import *
.
.
.
class foo():
.
.
def bar( self ):
print( "this is my overridden print statement" )
What am I missing about future, overrides, and print() here?
My environment is 2.6 and forward, but not 3.0.
Upvotes: 0
Views: 1195
Reputation: 4561
Another stackoverflow user provided most of the answer, but then apparently deleted it (?). Here is a working solution. Once again, I recognize this isn't necessarily a best practice, but it can be handy in certain situations.
Module MyOverrides.py:
from __future__ import print_function
import __builtin__
builtin_print = __builtin__.print
def print(*args, **kwargs):
.
.... whatever code you need here
.
return builtin_print(*args, **kwargs)
__builtin__.print = print
Module test.py:
from __future__ import print_function
from MyOverrides import *
.
.
.
As pointed out by another user, future import needs to happen in every module that intends to use future functionality.
Thanks to user @kindall who answered and then apparently withdrew the answer.
Upvotes: 1
Reputation: 280898
You can't (and shouldn't) have a global override that turns on a future statement. Since future statements affect the way a Python source file is parsed and compiled, before Python can even tell that MyOverrides
defines a print function, all future statements a module uses must be explicit. You can't import a future statement from another module.
The safest way to replace the print function is to explicitly use from __future__ import print_function
in all your modules, then import a replacement for print
from one of your modules. Don't replace __builtin__.print
.
If you want to affect all output to stdout, whether by print statement or print function, anywhere at all, you can replace sys.stdout
with a wrapper.
import sys
stdout = sys.stdout
class new_stdout(object):
def write(*args, **kwargs):
# do whatever
stdout.write(*args, **kwargs)
sys.stdout = new_stdout()
However, this is probably a bad idea, and it won't affect print statements or print functions that use an explicit file argument.
Upvotes: 1