Is it possible in Python to decorate a function so that its begin and end are logged?
<p>For logging, I would like each function to log its own name at the start and end of the function.</p>

<pre><code>def my_function():
    print("Enter my_function")
    # ...
    print("Leave my_function")
</code></pre>

<p>If I change the name of the function, I have to update these print messages as well. I am looking for a way to automate this.</p>

<pre><code>def my_decorator(func):
    print("Enter ", func.__name__)
    func()
    print("Leave ", func.__name__)

def my_function():
    # do the work
    pass

# main:
my_decorator(my_function)
</code></pre>

<p>Is this possible in a simple way, maybe using decorators? How would this look like if my_function had parameters?</p>

<p>Sure, it's really simple with star args and star kwargs. <code>functools.wraps</code> is used to rewrite any metadata (<code>__name__</code>, <code>__doc__</code> etc.) from input function to wrapper. If function object string representation is too verbose to you, you may use <code>print("Enter", f.__name__)</code> instead.</p>

<pre><code>import functools


def d(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        print("Enter", f)
        result = f(*args, **kwargs)
        print("Exit", f)
        return result
    return wrapper


@d
def my_func():
    print("hello")


@d
def my_func2(x):
    print(x)


my_func()
my_func2("world")
</code></pre>

<p>Output:</p>

<pre><code>Enter &lt;function my_func at 0x10ca93158&gt;
hello
Exit &lt;function my_func at 0x10ca93158&gt;
Enter &lt;function my_func2 at 0x10caed950&gt;
world
Exit &lt;function my_func2 at 0x10caed950&gt;
</code></pre>

python python-decorators