code: def get_callable_signature_as_string(the_callable):
      
      args, varargs, varkw, defaults = inspect.getargspec(the_callable)
      tmp_args = list(args)
      args_dict = {}
      if defaults:
          defaults = list(defaults)
      else:
          defaults = []
      while defaults:
          args_dict[tmp_args.pop()] = defaults.pop()
  
      while tmp_args:
          args_dict[tmp_args.pop()] = None
  
      args_list = []
      for arg in args:
          if args_dict[arg] is not None:
              args_list.append("%s=%s" % (arg, repr(args_dict[arg])))
          else:
              args_list.append(arg)
  
      if varargs:
          args_list.append("*%s" % varargs)
  
      if varkw:
          args_list.append("**%s" % varkw)
  
      args_string = ', '.join(args_list)
  
      return "def %s(%s)" % (the_callable.__name__, args_string)
docs: Return a string representing a callable.
  
      It is executed as if it would have been declared on the prompt.
  
      >>> def foo(arg1, arg2, arg3='val1', arg4='val2', *args, **argd):
      ...     pass
      >>> get_callable_signature_as_string(foo)
      def foo(arg1, arg2, arg3='val1', arg4='val2', *args, **argd)
  
      :param the_callable: the callable to be analyzed.
      :type the_callable: function/callable.
      :return: the signature.