I recently came across a handy function in Python that I would like to share with you. Consider the following piece of code:
# This code is not modifiable # a.py from scipy.spatial.distance import cdist def test_function(): coords = [(0,0), (3,4)] y = cdist(coords, coords, metric="euclidean") print(y)
This function uses an external distance function called
cdist() and calculates the euclidean distances of some (hardcoded) list of points. The resulting distance matrix between every pair of points is printed to the console. Up until now you used this function in your code, and everything was fine.
# Your code = modifiable from a import test_function test_function() # Prints # [[ 0. 5.] # [ 5. 0.]]
However, you decide that from now on you don't want to use the euclidean distance anymore. You want to use some other function instead of
cdist(). There is a problem: You cannot modify the above code. Your collegue wrote this above code and he is out of town. But you still have to use this function. A complete rewrite is also not possible, because you think the function is way too complex.
# Your new code from a import test_function from unittest import mock def rogue_cdist(x1, x2, metric): print("rogue_cdist called") with mock.patch('a.cdist', wraps=rogue_cdist): test_function() # Prints # rougue_cdist called # None
mock.patch() works by temporarily changing the object that a name points to with another one. You can use
mock.patch() with a context manager as shown above. In the above example, your new
rogue_cdist() function gets called, and now you are able to fill it with whatever distance metric you like.
I think this is very clever and clean and allows you to do modifications on existing code, without the need for the infamous copy-pasterino coding style.