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