0

Pretty simple question - I have searched but not found an answer to this question.

It might be a bit silly to do this but I was curious if it is possible to hook into the print(*arg, **kwarg) function of python 3.X and override it / add time.sleep(var) at the end of the invoke.

Of course I could just def another method and wrap it with a time.sleep(var) but I was just curious how one would go about overriding the pre-built functions.

Alper Kucukkomurler
  • 1,706
  • 2
  • 13
  • 19
  • 3
    `orig_print = print; print = new_function` should work. But I hardly think it's recommended. You'd better ask yourself why you would ever need to do such a thing. – Torxed May 28 '20 at 07:30
  • 1
    Please [edit] your question to clarify exactly what you need. Do you want to override ``print`` in a function, a code block, a module or an entire application? – MisterMiyagi May 28 '20 at 07:43

4 Answers4

3

If you want to patch any function globally, e.g. for testing / debugging purposes, the safest way is to use unittest.mock.patch():

def x():
    '''the code under test'''
    print('Hello, world!')

...
from unittest.mock import patch
orig_print = print

with patch('builtins.print') as m:
    def my_print(*args, **kwargs):
        orig_print('PATCHED:', *args, **kwargs)

    m.side_effect = my_print

    x()  # prints 'PATCHED: Hello, world!'

# prints 'Hello, world!', because the patch context is exited
# and the original function is restored: 
x() 
bereal
  • 32,519
  • 6
  • 58
  • 104
2

You could also try this one liner

out = print
print = lambda *args, **kwargs: [time.sleep(1), out(*args, **kwargs)]
Abhishek J
  • 2,386
  • 2
  • 21
  • 22
1

You can, you could do something like:

def new_print(*args, **kwargs):
    # Your new print function here
    pass

print = new_print

It's recommended that you save the old print function, and you'll need it if you want to use it inside your print function. You could do so like so

old_print = print
def new_print(*args, **kwargs):
    old_print(*args, **kwargs)

print = new_print

If you now want to add sleeping to that, you can do so by just putting it in the new function

import time

old_print = print
def new_print(*args, **kwargs):
    old_print(*args, **kwargs)
    time.sleep(5)

print = new_print
Minion3665
  • 879
  • 11
  • 25
  • I tried this, but in `old_print = print` I get an `UnboundLocalError: local variable 'print' referenced before assignment` (Python 3.4) – abu Feb 24 '22 at 10:49
  • 1
    @abu try `import builtins` and then `old_print = builtins.print` instead (or just use import and use `builtins.print` rather than saving it to old_print as well) – Minion3665 Feb 25 '22 at 00:38
0

Just to show that it would work, here an example. It is definitely not recommended though as you know.

import sys
def new_print(msg):
    sys.stdout.write("I always add this text\n")
    sys.stdout.write(msg)

print = new_print

print("Test")

I always add this text

Test

Nico Müller
  • 1,784
  • 1
  • 17
  • 37