3

I want to monkey patch a method of a library class to define a different default for a param. This fails:

from functools import partial

class A(object):
    def meth(self, foo=1):
        print(foo)

A.meth = partial(A.meth, foo=2)

a = A()
a.meth()

with:

Traceback (most recent call last):
  File "...", line 10, in <module>
    a.meth()
TypeError: meth() missing 1 required positional argument: 'self'

what is the correct way of doing this?

(Original code is using getattr on the method names in a loop)

The answers in the question linked involve defining a new module-level function - I would like to avoid a new function definition

9
  • Using @override? Commented Jan 31, 2019 at 12:23
  • Possible duplicate of Python: replacing a function within a class of a module Commented Jan 31, 2019 at 12:24
  • Oh I am not familiar with @override Commented Jan 31, 2019 at 12:24
  • Ignore my override statement, that might be my brain mixing in some Java syntax.. ouff.. That declaration might just be eye-candy-fluff. Sorry for the confusion. You should be able to just in-line replace A.meth = new_func and it should work. Commented Jan 31, 2019 at 12:27
  • 1
    @Mr_and_Mrs_D Note that A.meth is not a simple function, it is a descriptor. Hence you need to substitute it with an object that implements the descriptor protocol. Commented Jan 31, 2019 at 12:37

1 Answer 1

4

Use partialmethod:

In [32]: from functools import partialmethod

In [33]: A.meth = partialmethod(A.meth, foo=2)

In [34]: a = A()

In [35]: a.meth()
2
Sign up to request clarification or add additional context in comments.

1 Comment

Oh! What is the difference between partial and partialmethod (didn't know about the latter)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.