I am using python 2.6.6 and I need to overload the default python print function. I need to do it because this code may be used on a system where a built-in function has to be used to generate output, otherwise no output is displayed.
So, just for example, if you have a python script like this:
from __future__ import print_function
def NewPrint(Str):
with open("somefile.txt","a") as AFile:
AFile.write(Str)
def OverloadPrint():
global print
print = NewPrint
OverloadPrint()
print("ha")
It works fine. The input to the “overloaded” print is in the file specified by NewPrint.
Now with that in mind I would like to be able to run the couple of lines above and have print to do what NewPrint does during the entire execution of the script. Right now if I call a function from another module that uses print it will use the built-in print and not the one I just overwrote. I guess this has something to do with namespaces and built-ins, but my python is not good enough.
Edit:
I tried to keep simple, but looks like this caused more confusion…
- The function that overloads print will print to a GUI, so no need to care about redirection IF the function is overloaded.
-
I know my example does not do what the print function actually does. A better example of how I am thinking of coding it is (still not great I know):
def hli_print(*args, **kw): """ print([object, ...], sep=' ', end='\n', file=sys.stdout) """ sep = kw.get('sep', ' ') end = kw.get('end', '\n') File = kw.get('file', sys.stdout) args = [str(arg) for arg in args] string = sep.join(args) + end File.write(string) hli_Print(string) -
From 2 above you can see the function I have to use to print to the GUI “hli_Print” it is a C++ function exposed through a swig wrapper.
- We only use the standard library and our own swig wrappers, also our developers use print as a function (getting used to 3.X). So I did not really worry much about some other module calling print and having something else instead.
From all the comments I guess that just using some print_() function instead of print() (which is what we currently do) may be the best, but I got really curious to see if in python it would be possible to do what I described.
I don’t think your question makes any sense.
First, if you’re running Python 2.6, everything you import, etc., will be using
printstatements, even if your own module is using theprintfunction. So, overloading the function will not affect anything else.Second, you say “I need to do it because this code may be used on a system where a built-in function has to be used to generate output, otherwise no output is displayed.” Well, your
NewPrintis not a built-in function, so this won’t help anyway.It’s also worth noting that your
NewPrintdoesn’t implement most of the functionality of theprintfunction, and even the bit that it does implement, it does wrong (print(s)will printsfollowed by a newline). So, if you did replace the builtinprintfunction with yours, you’d just end up breaking most of your own code and any stdlib/third-party code you depend on.It may be that you can accomplish what you want by creating a file-like object that replaces
sys.stdout. Otherwise, I can’t see how anything could work. For example:But even if this works, it probably isn’t what you really want. For a quick&dirty script, on a platform with a defective shell, this is sometimes a handy idea. But otherwise, it will probably cause you more trouble in the long run than coming up with a better solution. Here’s just a few things that can go wrong (just as examples, not an exhaustive list)
>>in the shell, you could just call the script differently.stdoutis a tty before you make the change, and configure itself for interactive output.printing, but it was actually, say,logging or writing tosys.stderror doing something else, so you’ve given yourself a false sense of security that you’re now logging everything insomefile.txt, and won’t discover otherwise until 6 months later, when you desperately need that missing information to debug a problem at a customer site.Since you’ve edited the question, here’s some further responses:
Yes, that’s a more reasonable option. But I probably wouldn’t call it
print_. And it’s simpler to put the “do or do not” logic inside the function, instead of swapping implementations in and out of the global name (especially since you’re going to screw that up at some point if your code isn’t all in one big module).I worked on a project with a similar use case: We had messages we wanted to go to the syslogs, and also go to a GUI “log window” if it was open. So we wrote a
glogfunction that wrapped that up, and nobody complained that they wanted to writeprintinstead. (In fact, at least one guy on the team was very happy that he could useprintfor quick-and-dirty printouts while debugging without affecting the real output, especially when he had to debug the GUI logging code.)But that was just because we didn’t have any experience with the new (back then)
loggingmodule. Nowadays, I think I’d create aloggingHandlerimplementation that writes to the GUI window, and just add that handler, and use the standardloggingmethods everywhere. And it sounds like that might be the best option for you.Also, one last probably-irrelevant side issue:
So why not use 3.x in the first place? Obviously 3.x has the actual 3.x standard library, instead of something kind of close to the 3.x standard library if you do some
__future__statements, and SWIG works with 3.x…