Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monkey patching a @property

Is it at all possible to monkey patch the value of a @property of an instance of a class that I do not control?

class Foo:     @property     def bar(self):         return here().be['dragons']  f = Foo() print(f.bar)  # baz f.bar = 42    # MAGIC! print(f.bar)  # 42 

Obviously the above would produce an error when trying to assign to f.bar. Is # MAGIC! possible in any way? The implementation details of the @property are a black box and not indirectly monkey-patchable. The entire method call needs to be replaced. It needs to affect a single instance only (class-level patching is okay if inevitable, but the changed behaviour must only selectively affect a given instance, not all instances of that class).

like image 750
deceze Avatar asked Jul 23 '15 14:07

deceze


People also ask

What is monkey patching give example?

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 monkey patching in code?

Monkey patching is a technique used to dynamically update the behavior of a piece of code at run-time. A monkey patch (also spelled monkey-patch, MonkeyPatch) is a way to extend or modify the runtime code of dynamic languages (e.g. Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, etc.)

Is monkey patching a good practice?

But you should never consider this a standard technique and build monkey patch upon monkey patch. This is considered bad because it means that an object's definition does not completely or accurately describe how it actually behaves.

How does monkey patching work?

Monkey patching is reopening the existing classes or methods in class at runtime and changing the behavior, which should be used cautiously, or you should use it only when you really need to. As Python is a dynamic programming language, Classes are mutable so you can reopen them and modify or even replace them.


1 Answers

Subclass the base class (Foo) and change single instance's class to match the new subclass using __class__ attribute:

>>> class Foo: ...     @property ...     def bar(self): ...         return 'Foo.bar' ... >>> f = Foo() >>> f.bar 'Foo.bar' >>> class _SubFoo(Foo): ...     bar = 0 ... >>> f.__class__ = _SubFoo >>> f.bar 0 >>> f.bar = 42 >>> f.bar 42 
like image 108
Markus Meskanen Avatar answered Oct 18 '22 13:10

Markus Meskanen