Search code examples
pythonmonkeypatching

Monkey patching Python Property setters (and getters?)


So, monkey patching is pretty awesome, but what if I want to monkey patch a @property?

For example, to monkey patch a method:

def new_method():
    print('do stuff')
SomeClass.some_method = new_method

however, properties in python re-write the = sign.

Quick example, lets say I want to modify x to be 4. How would I go about doing that?:

class MyClass(object):
    def __init__(self):
        self.__x = 3

    @property
    def x(self):
        return self.__x

    @x.setter
    def x(self, value):
        if value != 3:
            print('Nice try')
        else:
            self.__x = value

foo = MyClass()
foo.x = 4
print(foo.x)
foo.__x = 4
print(foo.x)

Nice try

3

3


Solution

  • Using _ClassName__attribute, you can access the attribute:

    >>> class MyClass(object):
    ...     def __init__(self):
    ...         self.__x = 3
    ...     @property
    ...     def x(self):
    ...         return self.__x
    ...     @x.setter
    ...     def x(self, value):
    ...         if value != 3:
    ...             print('Nice try')
    ...         else:
    ...             self.__x = value
    ... 
    >>> foo = MyClass()
    >>> foo._MyClass__x = 4
    >>> foo.x
    4
    

    See Private Variables and Class-local References - Python tutorial, especially parts that mention about name mangling.