| Introduction to Monkey Patching | 
| monkey patching is a technique that allows modification or extention of the behavior of existing modules, classes, or functions at runtime without changing the original source code Applying Monkey Patchingsteps needed to apply the monkey patching 
 should use it carefully to avoid unexpected behaviors Monkey Patching Examplemonkey patch the Robot type with the add_speech function def add_speech(cls):
    cls.speak = lambda self, message: print(message)
    return cls
class Robot:
    def __init__(self, name):
        self.name = name
# assign the patch to the type
Robot = add_speech(Robot)
robot = Robot('Optimus Prime')
robot.speak('Hi')can also use a decorator to make the assign the monkey patchdef add_speech(cls):
    cls.speak = lambda self, message: print(message)
    return cls
@add_speech
class Robot:
    def __init__(self, name):
        self.name = name
robot = Robot('Optimus Prime')
robot.speak('Hi') | 
| When to use Monkey Patching | 
| should use monkey patching only when necessary because it can make code harder
                to understand and debug
                if using a third-party library and it has an urgent bug and cannot wait for official release can use the monkey patching to apply quick fixes while waiting for a proper solution want to add functionality to classes and cannot use other techniques like inheritance or composition |