Do something at the beginning & end of methods

class, python, python-3.x

Solution

You can use decorators (if you don't know them you can refer to PEP-318):

def decorator(method):
    def decorated_method(self, *args, **kwargs):
        # before the method call
        if self.busy:
            return None
        self.busy = True

        # the actual method call
        result = method(self, *args, **kwargs)  

        # after the method call
        self.busy = False

        return result

    return decorated_method

class Thing():
    def __init__(self):
        self.busy = False

    @decorator
    def func_1(self):
        ...

    @decorator
    def func_2(self):
        ...

You might want to use `functools.wraps` if you want the decorated method to "look like" the original method. The `@decorator` is just syntactic sugar, you could also apply the decorator explicitly:

class Thing():
    def __init__(self):
        self.busy = False

    def func_1(self):
        ...

    func_1 = decorator(func_1)  # replace "func_1" with the decorated "func_1"

In case you really want to apply it to all methods you can additionally use a class decorator:

def decorate_all_methods(cls):
    for name, method in cls.__dict__.items():
        if name.startswith('_'):  # don't decorate private functions
            continue 
        setattr(cls, name, decorator(method))
    return cls

@decorate_all_methods
class Thing():
    def __init__(self):
        self.busy = False

    def func_1(self):
        ...

    def func_2(self):
        ...

Problem

Is there an easy way to do something at the beginning and end of each function in a class? I've looked into `__getattribute__`, but I don't think that I can use it in this situation? Here's a simplified version of what I'm trying to do: ``` class Thing(): def __init__(self): self.busy = False def func_1(self): if self.busy: return None self.busy = True ... self.busy = False def func_2(self): if self.busy: return None self.busy = True ... self.busy = False ... ```

Original source