how __name__ change in python decorator
<p>Recently I'm learning Python decorator and the use of <code>functools.wraps</code>.</p>

<pre><code>def a():
    def b():
        def c():
            print('hello')
        return c
    return b


print a.__name__
#output:a
</code></pre>

<p>I understand why the output is a.But I don't know how <code>__name__</code> change in the following code.</p>

<pre><code>def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

@log('...')
def simple():
    print('*' * 20)

print simple.__name__
#output:wrapper
</code></pre>

<p>Why the output is 'wrapper' rather than 'decorator' or 'log'? </p>

<p>The point of decorators is to <em>replace</em> a function or class with what is returned by the decorator, when called with that function/class as argument. Decorators with arguments are a bit more convoluted, as you first call the outer method (<code>log</code>) to obtain a "parameterized" decorator (<code>decorator</code>), then you call that one and obtain the final function (<code>wrapper</code>), which will replace the decorated function (<code>simple</code>).</p>

<p>So, to give it some structure,</p>

<ol>
<li>call <code>log</code> with <code>'...'</code> as argument and obtain <code>decorator</code></li>
<li>call <code>decorator</code> with <code>simple</code> as argument and obtain <code>wrapper</code></li>
<li>replace <code>simple</code> with <code>wrapper</code></li>
</ol>

python