Skip to content Skip to sidebar Skip to footer

Two Methods Inherited From One Method In Class Are Different In Instances, Aren't They?

Can someone please explain why it is so? class Foo: def bar(self): pass a = Foo() b = Foo() a.bar == b.bar # False a.bar is b.bar # False I thought that they both in

Solution 1:

When you access a function through an instance that is defined on the class, a bound-method object is created each time. From the docs:

What exactly happens when a method is called? You may have noticed that x.f() was called without an argument above, even though the function definition for f() specified an argument. What happened to the argument? Surely Python raises an exception when a function that requires an argument is called without any — even if the argument isn’t actually used…

Actually, you may have guessed the answer: the special thing about methods is that the instance object is passed as the first argument of the function. In our example, the call x.f() is exactly equivalent to MyClass.f(x). In general, calling a method with a list of n arguments is equivalent to calling the corresponding function with an argument list that is created by inserting the method’s instance object before the first argument.

If you still don’t understand how methods work, a look at the implementation can perhaps clarify matters. When an instance attribute is referenced that isn’t a data attribute, its class is searched. If the name denotes a valid class attribute that is a function object, a method object is created by packing (pointers to) the instance object and the function object just found together in an abstract object: this is the method object.

Note, this happens every time you access a method:

>>> class Foo:
...    def bar(self): pass
...
>>> f = Foo()
>>> f.bar is f.bar
False

How does this work? Well, actually, functions are descriptor objects, note the presence of a __get__:

>>> def func(): pass
...
>>> func.__get__
<method-wrapper '__get__' of function object at 0x101e38ae8>

In other words, you can think of Python functions as being implemented thusly:

class Function(object):
    . . .
    def __get__(self, obj, objtype=None):
        "Simulate func_descr_get() in Objects/funcobject.c"
        if obj is None:
            return self
        return types.MethodType(self, obj)

Of course, they aren't implemented in Python (in CPython at least!).

Also note, accessing the function directly on the class, of course, doesn't do this (at least on Python 3, which you've tagged on your question):

>>> Foo.bar is Foo.bar
True

Post a Comment for "Two Methods Inherited From One Method In Class Are Different In Instances, Aren't They?"