0

In original.py, it is not controlled by myself

def func():
 print("func")

Is there a way to patch original.func?

patch_original.py, it is controlled by myself

def patched_func():
 original.func()
 print("patched_func")

call.py

import original # can not change this
import patch_original
func()

I want to be able to print

func

patched_func


Update: original.py is not under my control.

patch_original.py is fully controllable.

call.py is partially under my control, it has already import original

asked May 14, 2017 at 3:50

3 Answers 3

3

This sort of patch is perfect for the decorator pattern:

In original.py:

def func():
 print("func")

In patch_original:

def patch(f): # this function is a decorator
 def p():
 f()
 print("patched_func")
 return p

In call.py:

import original
import patch_original
func = patch_original.patch(original.func) # here we decorate `original.func`
func()

Running call.py:

Juans-MacBook-Pro:temp juan$ python call.py
func
patched_func
Juans-MacBook-Pro:temp juan$

Then you can resuse this patch as you define new function in call.py:

import original
import patch_original
func = patch_original.patch(original.func)
func()
@patch_original.patch # decorator syntax
def func2():
 print("func2")
func2()

And running this:

Juans-MacBook-Pro:temp juan$ python call.py
func
patched_func
func2
patched_func
answered May 14, 2017 at 4:01
Sign up to request clarification or add additional context in comments.

6 Comments

This looks interesting, my goal is to minimize the change against call.py, and do most work in module patch_original, can I move the patching statement to patch_original?
Hm, honestly, I would keep the patching where it's going to be used, at the top. You won't have to modify any of the rest of the code. But I suppose you could do it in patch_original but you have to from patch_original import func.
Yes, that's true. The background: I need to provide patch_original to my customers in order to provide some extra services. They will use it in online python environment. That means minimizing the changes to their main script will provide better user experience.
@user1633272 Also, note, if you import original in call.py, then really func will be original.func.
Does that mean I have to explicitly call 'func = xxx' assignment statement in call.py? Actually I have about 6 functions need to be patched. That's why I want to hide it from call.py.
|
0

Do this in patch_original.py:

import original
_original_func = original.func
def patched_func():
 _original_func()
 print("patched_func")

Then in your main script:

import patch_original
func = patch_original.patched_func
answered May 14, 2017 at 3:58

Comments

0

original.py

def func():
 print("func")

patch_original.py

import original
def patched_func():
 original.func()
 print("patched_func")

call.py

import original
import patch_original
patch_original.patched_func()
answered May 14, 2017 at 4:03

2 Comments

The environment needs to import original in call.py. And I shouldn't change the calling statement in call.py.
Ok you can have "original.py" imported but never used. I updated.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.