pythonprogramming-languagesmonkeypatchingfluent-interface

Can you monkey patch methods on core types in Python?


Ruby can add methods to the Number class and other core types to get effects like this:

1.should_equal(1)

But it seems like Python cannot do this. Is this true? And if so, why? Does it have something to do with the fact that type can't be modified?

Rather than talking about different definitions of monkey patching, I would like to just focus on the example above. I have already concluded that it cannot be done as a few of you have answered. But I would like a more detailed explanation of why it cannot be done, and maybe what feature, if available in Python, would allow this.

To answer some of you: The reason I might want to do this is simply aesthetics/readability.

 item.price.should_equal(19.99)

This reads more like English and clearly indicates which is the tested value and which is the expected value, as supposed to:

should_equal(item.price, 19.99)

This concept is what Rspec and some other Ruby frameworks are based on.


Solution

  • What exactly do you mean by Monkey Patch here? There are several slightly different definitions.

    If you mean, "can you change a class's methods at runtime?", then the answer is emphatically yes:

    class Foo:
      pass # dummy class
    
    Foo.bar = lambda self: 42
    
    x = Foo()
    print x.bar()
    

    If you mean, "can you change a class's methods at runtime and make all of the instances of that class change after-the-fact?" then the answer is yes as well. Just change the order slightly:

    class Foo:
      pass # dummy class
    
    x = Foo()
    
    Foo.bar = lambda self: 42
    
    print x.bar()
    

    But you can't do this for certain built-in classes, like int or float. These classes' methods are implemented in C and there are certain abstractions sacrificed in order to make the implementation easier and more efficient.

    I'm not really clear on why you would want to alter the behavior of the built-in numeric classes anyway. If you need to alter their behavior, subclass them!!