0

I want to invoke a method with arguments on an instance of a subclass, given a reference to a method. The problem: which method is dynamic, and is one of the (unbound) methods of the parent class.

class Parent:
    def method(self, x):
        print(f'Parent:foo called with {x}')

    def another(self, x):
        pass

class Child(Parent):
    def method(self, x):
        print(f'Child:foo called with {x}')

    def another(self, x):
        pass

# Change this
def problem_func(target: Parent, ref):
    meth, args = ref
    meth(target, args)

c = Child()
# Change this too
ref = (Parent.method, 42)
problem_func(c, ref)

The above prints 'Parent:foo called with 42'. I'd like a solution that prints 'Child:foo called with 42'.

Essentially, I'd like a way to bind a method to an instance and have it follow the Python inheritance/MRO rules. Even better, I'd like a closure with that and some arguments, but that might be too much to ask.

Obviously, I could change ref to (Child.method, 42) but that's defeating the purpose. The point is there are multiple subclasses of Parent, and I'll be iterating through a list of those and I want to apply the "same" method (with appropriate overridden behavior) to them all.

One solution I've found is to replace meth(target, args) with getattr(target, meth.__name__)(args). I'm looking for a built-in answer.

Edit: essentially I'm looking for the equivalent to pointers-to-members from C++. See https://stackoverflow.com/a/60023/6518334

Nic Watson
  • 388
  • 3
  • 5
  • `getattr(target, meth.__name__)(args)` also works if the subclass doesn't override the method as `getattr` follows the MRO then. – Michael Butscher Nov 12 '19 at 04:43
  • I see no reason why not to just directly call `target.method(arg)`. What problem do you try to solve? Or do you have educational purposes may be? Possibly it looks like XY problem. – 4xy Nov 12 '19 at 19:01
  • Which method of target is passed in as a parameter. The only restriction on the parameter passed in is that it is a method of Parent. – Nic Watson Nov 12 '19 at 20:49
  • 1
    `Parent.method` and `Child.method` both evaluate to ordinary `function` objects that have no concept of what class they were defined in. `meth` has no reason to care what the type of its first argument is. – chepner Nov 13 '19 at 21:56

0 Answers0