Object Method Reference Variable is not the Object method

Question:

After initializing an object attribute to point to an object method, the variable will not be evaluated as being the same (using ‘is’) as the object method. It will still be evaluated as having equality (==) with the method.

class SomeClass:
    def __init__(self):
        self.command = self.do_something

    def do_stuff(self):
        print('c1:', id(self.command))
        print('c2:', id(self.do_something))
        if self.command is self.do_something:
            return 'Commands match (is)'
        elif self.command == self.do_something:
            return 'Commands match (==)'
        return 'Commands do not match at all'
    def do_something(self):
        pass


some_object = SomeClass()
print(some_object.do_stuff())
print()

def some_func():
    pass
command = some_func
print('c1:', id(some_func))
print('c2:', id(command))
if some_func is command:
    print('Commands match (is)')
else:
    'Commands do not match at all'

I was expecting the ids of self.command and self.do_something to be the same just like some_func and command ids are the same.

Asked By: Patrick

||

Answers:

Each time you access a method via an instance, you get back a new instance of method that wraps both the instance and the underlying function. Two method instances compare as equal if they wrap the same instance and the same function. (This is not documented anywhere as far as I know—it’s not mentioned in the documentation for instance method objects—but can be seen in the CPython source code.)

So even though self.command (a previously created bound method) and self.do_something are distinct instances of method, they both wrap the same instance (self) of SomeClass and the same function (SomeClass.do_something).

Details on how function values produce method instances can be found in the Descriptor HowTo guide.

(Instance method objects are documented in Section 3.2 of the language documentation.)

Answered By: chepner
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.