Globally override built-in print function?
Lie Ryan
lie.1296 at gmail.com
Fri Apr 16 04:14:26 EDT 2010
On 04/16/10 12:17, Dave W. wrote:
>>> I naively thought I could capture output from exec()'ed print
>>> invocations by (somehow) overriding 'print' globally. But this
>>> seems not to be possible. <snip>
>
>>
>> old_print = __builtins__.print
>> __builtins__.print = printhook
>> yield
>> __builtins__.print = old_print
>
> I'm pretty sure this is semantically equivalent to my original code,
> but I gave it a try anyway. FWIW, it doesn't work, either. :-}
>
>> But you really should replace sys.stdout and sys.stderr instead.
>
> I'm starting to believe it, but... I thought that one of the
> benefits of making print a function was that it *could* be globally
> replaced. So far I've had no luck injecting a custom print
> replacement into other modules. Is this really not possible?
No, the benefit of 'from __future__ import print_function' is for easing
transition to python 3. The ability to replace print globally only works
in python 3, after applying the change Robert Kern and turning raw_input
to input, the code works in python 3:
lieryan at compaq ~/junks $ python3 printhook.py
Python 3.1.2 (r312:79147, Apr 16 2010, 16:58:34)
[GCC 4.3.4]
linux2
Type "help", "copyright", "credits" or "license" for more info.
>>> print(32)
printhook(): 32
Note that assigning to __builtins__.print is different from assigning to
print. With the latter, you shadowed the print function in
__builtins__.print by putting your own print in the global namespace
(which in python really means module-level); while with the former
you're switching print in the interpreter level, the true global namespace.
========================================================
### File test.py ###
from __future__ import print_function
import sys
from code import InteractiveInterpreter
from contextlib import contextmanager
def printhook(*args):
sys.stdout.write("printhook(): {0}\n".format(repr(args[0])))
@contextmanager
def global_printhook(printhook):
global print
print = printhook
yield
print = __builtins__.print
py = InteractiveInterpreter()
if not hasattr(sys, "ps1"): sys.ps1 = ">>> "
if not hasattr(sys, "ps2"): sys.ps2 = "... "
banner = ("Python %s\n%s\n" % (sys.version, sys.platform) +
'Type "help", "copyright", "credits" or "license" '
'for more info.\n')
sys.stdout.write(banner)
sys.stdout.write(sys.ps1)
while True:
try:
with global_printhook(printhook):
result = py.runsource(input())
if result is None:
sys.stdout.write(sys.ps2)
elif result is True:
py.runcode(result)
except EOFError:
break
else:
sys.stdout.write(sys.ps1)
============================================================
More information about the Python-list
mailing list