Difference between Context Managers and Decorators in Python : <p>What is the main difference between the two? I have been studying Python and came across them. A decorator is essentially a function that wraps another function and you can do anything before and after a particular function executes.</p>

<pre><code>def my_decorator(some_function):
    def wrapper(*args, **kwargs):
        print("Do something before the function is called")
        some_function(*args, **kwargs)
        print("Do something after the function is called")

    return wrapper

@my_decorator
def addition(a, b):
    result = a+b
    print("Addition of {} and {} is {}".format(a,b,result))
</code></pre>

<p>But after studying Context Manager, I couldn't help but notice that it too has a <strong>enter</strong> and <strong>exit</strong> where you could do most similar operations. </p>

<pre><code>from contextlib import contextmanager

@contextmanager
def open_file(path, mode):
    the_file = open(path, mode)
    yield the_file
    the_file.close()

files = []

for x in range(100000):
    with open_file('foo.txt', 'w') as infile:
        files.append(infile)

for f in files:
    if not f.closed:
        print('not closed')
</code></pre>

<p>Everything before yield is taken as part of the "enter" and everything after a part of "exit". </p>

<p>Although both Context Managers and Decorators are syntactically different, their behaviors can be looked upon as similar. So what is the difference? What are the different scenarios when one should use either of them?</p>
