Decorators in class methods: compatibility with 'getattr'
<p>I need to make wrappers for class methods, to be executed before and/or after the call of a specific method.</p>

<p>Here is a minimal example:</p>

<pre><code>class MyClass:

    def call(self, name):
        print "Executing function:", name
        getattr(self, name)()

    def my_decorator(some_function):
        def wrapper():
            print("Before we call the function.")
            some_function()
            print("After we call the function.")
            return wrapper

    @my_decorator
    def my_function(self):
        print "My function is called here."


engine = MyClass()
engine.call('my_function')
</code></pre>

<p>This gives me an error at the line <code>getattr(self, name)()</code>: </p>

<blockquote>
  <p>TypeError: 'NoneType' object is not callable</p>
</blockquote>

<p>If I comment out the decorator before the class method, it works perfectly:</p>

<pre><code>class MyClass:

    def call(self, name):
        print "Executing function:", name
        getattr(self, name)()

    def my_decorator(some_function):
        def wrapper():
            print("Before we call the function.")
            some_function()
            print("After we call the function.")
            return wrapper

    # @my_decorator
    def my_function(self):
        print "My function is called here."


engine = MyClass()
engine.call('my_function')
</code></pre>

<p>The output is:</p>

<blockquote>
  <p>Executing function: my_function</p>
  
  <p>My function is called here.</p>
</blockquote>

<p>The decorator itself is identical to textbook examples. It looks like something goes wrong at a low level when calling a decorated method in Python with <code>getattr</code>.</p>

<p>Do you have any ideas on how to fix this code?</p>

<p>This has nothing to do with <code>getattr()</code>. You get the exact same error when you try to call <code>my_function()</code> directly:</p>

<pre><code>&gt;&gt;&gt; engine.my_function()
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
TypeError: 'NoneType' object is not callable
</code></pre>

<p>You have 2 problems:</p>

<ul>
<li><p>Your decorator never returns the <code>wrapper</code>, so <code>None</code> is returned instead. This return value replaces <code>my_function</code> and is the direct cause of your error; <code>MyClass.my_function</code> is set to <code>None</code>:</p>

<pre><code>&gt;&gt;&gt; MyClass.my_function is None
True
</code></pre></li>
<li><p>Your wrapper takes no arguments, including <code>self</code>. You'll need this for it to work once you do return it properly.</p></li>
</ul>

<p>The first problem is fixed by un-indenting the <code>return wrapper</code> line; it is currently part of the <code>wrapper</code> function <em>itself</em>, and should be part of <code>my_decorator</code> instead:</p>

<pre><code>def my_decorator(some_function):
    def wrapper(self):
        print("Before we call the function.")
        # some_function is no longer bound, so pass in `self` explicitly
        some_function(self)
        print("After we call the function.")
    # return the replacement function
    return wrapper
</code></pre>

python oop metaprogramming decorator python-decorators