1

Consider the following code:

def a():
    pass

def comp():
    for f in (a,):
        if f is a:
            print("Identity")
        elif f == a:
            print("Equality")

comp()

I create a function a, and a function comp which checks, for all functions in the tuple (a,), if they're either identical to a (f is a), or equal to it (f == a). Unsurprisingly, this code prints the word "Identity".

However, this is no longer the case if I turn those functions into instance methods of a class Test:

class Test(object):
    def a(self):
        pass

    def comp(self):
        for f in (self.a,):
            if f is self.a:
                print("Identity")
            elif f == self.a:
                print("Equality")

t = Test()
t.comp()

To my great surprise, this prints "Equality" instead of "Identity". Indeed, if we put print(id(f), id(self.a)) inside the for loop, it will print different identity values. As I'd expect, both identities are different from id(Test.a).

Why is this? Why do the methods seemingly get copied by the for loop, when the plain functions do not?

acdr
  • 4,538
  • 2
  • 19
  • 45
  • 2
    What did you expect their relationship to be? Method objects are created each time you look them up on an instance (they are the result of *binding* the function to an instance). – Martijn Pieters May 17 '19 at 11:35

0 Answers0