Bound methods in Python are one of the keys to enlightenment to understanding its object system -- that self isn't magic and you could implement it yourself (for example having instance methods take a self, and cls parameter) if you wanted. One fun exercise is implementing an object that can "adopt" loose functions.
def some_random_function(self)
print(self.internal_state)
...
mymagicobject.func = some_random_func
mymagicobject.func() # -> prints the internal state of the object