From: Dave W. on 15 Apr 2010 19:08 I naively thought I could capture output from exec()'ed print invocations by (somehow) overriding 'print' globally. But this seems not to be possible. Or at least not easy: c:\d>test.py Python 2.6.2 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)] win32 Type "help", "copyright", "credits" or "license" for more info. >>> print("Hello?") Hello? >>> My custom print function isn't being called (see code below), I guess because its only being overridden in the current module? Is there some way to make InteractiveInterpreter/exec use my print function, or is this simply not possible? ---------- ### 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(raw_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)
From: Robert Kern on 15 Apr 2010 19:18 On 2010-04-15 18:08 PM, 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. Or at least not easy: > > c:\d>test.py > Python 2.6.2 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit > (Intel)] win32 > Type "help", "copyright", "credits" or "license" for more info. >>>> print("Hello?") > Hello? >>>> > > My custom print function isn't being called (see code below), > I guess because its only being overridden in the current module? > Is there some way to make InteractiveInterpreter/exec use my print > function, or is this simply not possible? > > ---------- > > ### 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 old_print = __builtins__.print __builtins__.print = printhook yield __builtins__.print = old_print But you really should replace sys.stdout and sys.stderr instead. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
From: Dave W. on 15 Apr 2010 22:17 > > 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?
From: Peter Otten on 16 Apr 2010 03:49 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. Or at least not easy: Assigning a new function to the global print name affects only print() calls within your script, not the REPL. You have to redirect the latter and make sure that it is actually used instead of the print statement. The easiest way I see to achieve that would be: py.runsource("from __future__ import print_function") py.runsource("from __main__ import printhook as print") Peter
From: Lie Ryan on 16 Apr 2010 04:14 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(a)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) ============================================================
|
Next
|
Last
Pages: 1 2 Prev: python wia and RegisterEvent Next: how to get elements of a com object (wmi log events) |