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>Some basics:</p>

<pre><code>@decorator
def f():
    pass
</code></pre>

<p>is equivalent to:</p>

<pre><code>def f():
    pass
f = decorator(f)
</code></pre>

<p>Decorator with args:</p>

<pre><code>@decorator(*args, **kwargs)
def f():
    pass
</code></pre>

<p>is equivalent to:</p>

<pre><code>def f():
    pass
decorator_instance = decorator(*args, **kwargs)
f = decorator_instance(f)
</code></pre>

<p>With knowing so, we may rewrite your example to:</p>

<pre><code>def simple():
    print('*' * 20)

log_instance = log('...')
simple = log_instance(simple)
</code></pre>

<p>Let's analyze what happens in last two lines:</p>

<ul>
<li><code>log_instance</code> is a <code>decorator</code> function, and text variable within it is equal to '...'</li>
<li>Since <code>decorator</code> (regardless of <code>text</code> value) returns function named wrapper, <code>simple</code> is replaced with function named <code>wrapper</code></li>
</ul>

python