Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to overload print function to expand its functionality?

I am wondering if the build-in function print could be overridden so that the following statement will write to the console and a file at the same time.

print("test0","test1","test2",sep='\n') 

Also, may I know if it is possible to modify the source code of the build-in print function?

like image 312
lxjhk Avatar asked Dec 23 '14 13:12

lxjhk


People also ask

Can we override print function in Python?

By default, Python's print statement ends each string that is passed into the function with a newline character, \n . This behavior can be overridden with the function's end parameter, which is the core of this method.

What is print () function explain with example?

Definition and Usage The print() function prints the specified message to the screen, or other standard output device. The message can be a string, or any other object, the object will be converted into a string before written to the screen.

How many arguments can the print function take?

Python print() Function Parameters. There seem to be 5 arguments that the print() function accepts.


2 Answers

You can create a class with a write method and inside of that method you can print both stdout as well as write to the file.

import sys

class A(object):
    def __init__(self, f):
        self.f = open(f, 'w') 

    def __enter__(self):
        return self   # return instance of A which is assign to `f`.

    def write(self, text):
        sys.stdout.write(text)  # print to the shell
        self.f.write(text) # write in the file

    def __exit__(self, *args):
        self.f.close()
        return True

with A('foo.txt') as f:
    print("test0","test1","test4",sep='\n', file=f) #`file = f` calls `write` method
like image 190
Vishnu Upadhyay Avatar answered Oct 21 '22 12:10

Vishnu Upadhyay


Use a decorator. Simplified example:

def my_decorator(func):
    def wrapped_func(*args,**kwargs):
        return func("I've been decorated!",*args,**kwargs)
    return wrapped_func

print = my_decorator(print)

Test:

print("TESTING") #I've been decorated! TESTING

So to print to a file at the same time you might do:

def super_print(filename):
    '''filename is the file where output will be written'''
    def wrap(func):
        '''func is the function you are "overriding", i.e. wrapping'''
        def wrapped_func(*args,**kwargs):
            '''*args and **kwargs are the arguments supplied 
            to the overridden function'''
            #use with statement to open, write to, and close the file safely
            with open(filename,'a') as outputfile:
                outputfile.write(*args,**kwargs)
            #now original function executed with its arguments as normal
            return func(*args,**kwargs)
        return wrapped_func
    return wrap

print = super_print('output.txt')(print)

If you compare this to the example above, you'll see there is an additional closure in this situation (i.e., return wrapped_func AND return wrap instead of just return wrapped_func). This second closure allows us to send an additional argument (filename) into the wrapper/decorator function.

The syntax of this last line looks a little weird, but this is the correct way. The call to super_print('output.txt') returns an object which is then given the print function object as an additional argument. This whole thing works via closures; research them if you aren't up to speed.

Then:

print('test')

test will be written to console output and to output.txt.

like image 30
Rick supports Monica Avatar answered Oct 21 '22 10:10

Rick supports Monica