1

Edit: this question is based on two mistakes: not originally yincluding self in methods and assuming unbounded methods would not exhibit polymorphism, but they do. I voted to close it.

I can take a method as a function-valued object in Python:

class A:
    def foo(self):
        return "Hi, I'm A.foo"

f = A.foo
a = A()
print(f(a))

produces Hi, I'm A.foo.

So far so good. However, f won't work for sub-classes:

class B(A):
    def foo(self):
        return "Hi, I'm B.foo"

f = A.foo
b = B()
f(b)

still produces Hi, I'm A.foo, whereas b.foo() produces Hi, I'm B.foo. In other words, polymorphism does not apply.

Question: is there a way to get a function-valued object in f so that f(x) == x.foo() whenever isinstance(x, A)?

In other words, how do I complete the snippet below for things to work?

class A:
    def foo(self):
        return "Hi, I'm A.foo"

class B(A):
    def foo(self):
        return "Hi, I'm B.foo"

f = <WHAT DO I PUT HERE?>
a = A()
b = B()
assert f(a) == a.foo()
assert f(b) == b.foo()
user118967
  • 4,895
  • 5
  • 33
  • 54

1 Answers1

1

Your can pull the class name out like so:

class A:
    def foo(self):
        return "Hi, I'm {}.foo".format(self.__class__.__name__)

class B(A):
    def foo(self):
        return "Hi, I'm {}.foo".format(self.__class__.__name__)

f = A.foo  # this could be A or B, doesn't matter
a = A()
b = B()
assert f(a) == a.foo()
assert f(b) == b.foo()

Note that because B inherits from A, you don't even need the foo method there:

class A:
    def foo(self):
        return "Hi, I'm {}.foo".format(self.__class__.__name__)

class B(A):
    pass

f = A.foo
a = A()
b = B()
assert f(a) == a.foo()
assert f(b) == b.foo()
JacobIRR
  • 8,545
  • 8
  • 39
  • 68
  • Sorry, my mistake. I inferred that this didn't work based on some more complicated code, but the problem must be elsewhere. I should have run my example first. – user118967 Aug 05 '20 at 19:39