code: def reusable(func):
      
      sig = signature(func)
      origin = func
      while hasattr(origin, '__wrapped__'):
          origin = origin.__wrapped__
      return type(
          origin.__name__,
          (ReusableGenerator, ),
          dict([
              ('__doc__',       origin.__doc__),
              ('__module__',    origin.__module__),
              ('__signature__', sig),
              ('__wrapped__',   staticmethod(func)),
          ] + [
              (name, property(compose(itemgetter(name),
                                      attrgetter('_bound_args.arguments'))))
              for name in sig.parameters
          ] + ([
              ('__qualname__',  origin.__qualname__),
          ] if sys.version_info > (3, ) else [])))
docs: Create a reusable class from a generator function
  
      Parameters
      ----------
      func: GeneratorCallable[T_yield, T_send, T_return]
          the function to wrap
  
      Note
      ----
      * the callable must have an inspectable signature
      * If bound to a class, the new reusable generator is callable as a method.
        To opt out of this, add a :func:`staticmethod` decorator above
        this decorator.