Use context manager as a function
<p>I'd like to make a function which would also act as context manager if called with <code>with</code> statement. Example usage would be:</p>

<pre><code># Use as function    
set_active_language("en")

# Use as context manager
with set_active_language("en"):
    ...
</code></pre>

<p>This is very similar to how the standard function <code>open</code> is used.</p>

<p>Here's the solution I came up with:</p>

<pre><code>active_language = None  # global variable to store active language

class set_active_language(object):

    def __init__(self, language):
        global active_language
        self.previous_language = active_language
        active_language = language

    def __enter__(self):
        pass

    def __exit__(self, *args):
        global active_language
        active_language = self.previous_language
</code></pre>

<p>This code is not thread-safe, but this is not related to the problem. </p>

<p>What I don't like about this solution is that class constructor pretends to be a simple function and is used only for its side effects.</p>

<p>Is there a better way to do this?</p>

<p>Note that I haven't tested this solution.</p>

<p>Update: the reason why I don't want to split function and context manager into separate entities is is naming. The function and the context manager do the same thing, basically, so it seems reasonable to use one name for both. Naming the context processor would be problematic if I wanted to keep it separate. What should it be? <code>active_language</code>? This name may (and will) collide with variable name. <code>override_active_language</code> might work, though.</p>

<p>Technically no, you cannot do this.  But you can fake it well enough that people (who didn't overthink it) wouldn't notice.</p>

<pre><code>def set_active_language(language):
    global active_language
    previous_language = active_language
    active_language = language

    class ActiveScope(object):
        def __enter__(self):
            pass

        def __exit__(self, *args):
            global active_language
            active_language = previous_language

    return ActiveScope()
</code></pre>

<p>When used as a function the <code>ActiveScope</code> class is just a slightly wasteful no-op.</p>

python