Skip to content

Instantly share code, notes, and snippets.

@mara004
Created August 8, 2025 13:45
Show Gist options
  • Save mara004/88835190749e5657f9c26490dab8b4f2 to your computer and use it in GitHub Desktop.
Save mara004/88835190749e5657f9c26490dab8b4f2 to your computer and use it in GitHub Desktop.
Exit hanlder for function
# SPDX-FileCopyrightText: 2025 geisserml <[email protected]>
# SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
import functools
class finally_decorator:
def __init__(self, callback):
self._callback = callback
def __call__(self, func):
@functools.wraps(func)
def wrapped(*args, **kwargs):
try:
return func(*args, **kwargs)
finally:
self._callback()
return wrapped
@finally_decorator(lambda: print("Exit test"))
def test(arg, kwarg=1):
print(f"Enter test({arg}, {kwarg})")
test(0)
@mara004
Copy link
Author

mara004 commented Aug 8, 2025

This avoids having a try/finally or with block in the function itself (useful for long function content).

@mara004
Copy link
Author

mara004 commented Aug 8, 2025

Otherwise, you could do this manually:

def _test_impl():
    print("Long implementation here ...")

def test():
    try:
        _test_impl()
    finally:
        print("Exit handler")

@mara004
Copy link
Author

mara004 commented Aug 23, 2025

My initial motivation for this was to clean up global state, but refactoring to avoid globals in the first place turned out to be the better solution in that case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment