[Answered ]-Django monkey patching model with method seems to work correctly as instance method – am I missing something?

1👍

This is expected and consistent behaviour. Doing this:

setattr(Foo, 'mysomething', something)

is functionally equivalent to doing this (just that you do it later, rather than when the class is defined):

class Foo:

    def mysomething(self):
        return something(self)

In Python, defining a method on a class without any decorator implies it is an instance method – i.e, that the first argument to the method will be the instance itself. Defining a method via setattr does not change this fact – it’s just a less obvious way of doing it.

Consider this alternative, which illustrates the point:

# Now we wrap `something` in `staticmethod`
setattr(Foo, 'mysomething', staticmethod(something))

is equivalent to:

class Foo:

    @staticmethod
    def mysomething():
        return something()

Now, because it’s been added as a static method, it will not be passed an instance of the class when you call it, and you’ll get an error if you try calling Foo().mysomething():

TypeError: something() missing 1 required positional argument: 'obj'

Leave a comment