Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

Update: 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.

like image 513
airportyh Avatar asked Oct 10 '08 18:10

airportyh


People also ask

How does monkey patching work in Python?

In Python, the term monkey patch refers to dynamic (or run-time) modifications of a class or module. In Python, we can actually change the behavior of code at run-time. We use above module (monk) in below code and change behavior of func() at run-time by assigning different value.

What is multi patching in Python?

Monkey Patching is an exciting topic of Python. Monkey-patching is a term that refers to modifying a class or module at a run time. In simple words, a class or module's work can be changed at the runtime. Let's understand this concept by real-life example.

What is monkey patching in Javascript?

Monkey patching is more a way for debugging, experiencing, patching, or hacking existing code than rather a long-term solution for a code base, even if it could be used as a natural solution in a few specific cases.


2 Answers

No, you cannot. In Python, all data (classes, methods, functions, etc) defined in C extension modules (including builtins) are immutable. This is because C modules are shared between multiple interpreters in the same process, so monkeypatching them would also affect unrelated interpreters in the same process. (Multiple interpreters in the same process are possible through the C API, and there has been some effort towards making them usable at Python level.)

However, classes defined in Python code may be monkeypatched because they are local to that interpreter.

like image 53
John Millikin Avatar answered Oct 13 '22 09:10

John Millikin


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!!

like image 34
Dan Lenski Avatar answered Oct 13 '22 10:10

Dan Lenski