I'd like to make a function which would also act as context manager if called with with
statement. Example usage would be:
# Use as function
set_active_language("en")
# Use as context manager
with set_active_language("en"):
...
This is very similar to how the standard function open
is used.
Here's the solution I came up with:
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
This code is not thread-safe, but this is not related to the problem.
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.
Is there a better way to do this?
Note that I haven't tested this solution.
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? active_language
? This name may (and will) collide with variable name. override_active_language
might work, though.
Technically no, you cannot do this. But you can fake it well enough that people (who didn't overthink it) wouldn't notice.
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()
When used as a function the ActiveScope
class is just a slightly wasteful no-op.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With