AttributeError not generated in case of passing method reference
<p>I have one simple doubt with respect to python 2.7:</p>

<p>I have created an abstract base class and a child class:</p>

<pre><code>from abc import ABCMeta, abstractmethod


class Base:

    """
    Abstract base class for all entities.
    """
    __metaclass__ = ABCMeta

    def __init__(self, name):
        self.name = name

    def send_data(self):
        self.send_data()

class Child (Base):

    def __init__(self, name):
        super(Child, self).__init__(name=name)
</code></pre>

<p>When the object for the child class is created and the send_method is called I get the following error which is the expected behavior:</p>

<pre><code>sample = Child('test')
sample.send_data()

# â¦
RuntimeError: maximum recursion depth exceeded
</code></pre>

<p>But when the send_method reference is passed in the base class and call is made to send_method by creating the child class object I think the expected behavior is to receive <code>AttributeError</code> but I am surprised to see no error is generated. Please explain.</p>

<pre><code>from abc import ABCMeta, abstractmethod

class Base:

    """
    Abstract base class for all entities.
    """
    __metaclass__ = ABCMeta

    def __init__(self, name, parent):
        self.name = name
        self.parent = parent

    def send_data(self):
        self.send_data

sample = Child('test')
sample.send_data()

# No error
</code></pre>

<p>In your first example you simply created a recursive function:</p>

<pre><code>def send_data(self):
    self.send_data()
</code></pre>

<p>This calls itself, without end, and that's why you end up with a recursion depth exception.</p>

<p>Your second example <em>doesn't actually call the method</em>:</p>

<pre><code>def send_data(self):
    self.send_data
</code></pre>

<p>The <em>only</em> difference here is that you forgot to use <code>()</code>.</p>

<p>None of this has anything to do with abstract base classes or inheritance. You didn't mark the <code>send_data</code> function as abstract, and even if you did, all that using <code>abstractmethod</code> does is make it impossible to create an instance of a class without a concrete implementation to replace it.</p>

<p>You won't get an <code>AttributeError</code> just because you defined a method on an <code>ABCMeta</code> class. And note that methods are just attributes on a class; they don't live a separate namespace. <code>self.send_data</code> references the bound method, not some other attribute that is separate. Referencing the method without calling it does nothing otherwise.</p>

python abstract-base-class