import inspect
import functools


def onetimemethod(method):
    """Decorator for methods which need to be executable only once."""
    if not inspect.isfunction(method):
        raise TypeError('Not a function.')
    has_run = {}
    @functools.wraps(method)
    def wrapped(self, *args, **kwargs):
        """Wrapped method being run once and only once."""
        nonlocal has_run
        if has_run.setdefault(id(self), False):
            raise RuntimeError(
                "One-time method '%s' cannot be re-run for this instance."
                % method.__name__
            )
        has_run[id(self)] = True
        return method(self, *args, **kwargs)
    return wrapped