code: def model_to_string(self, num_iteration=None, start_iteration=0):
          
          if num_iteration is None:
              num_iteration = self.best_iteration
          buffer_len = 1 << 20
          tmp_out_len = ctypes.c_int64(0)
          string_buffer = ctypes.create_string_buffer(buffer_len)
          ptr_string_buffer = ctypes.c_char_p(*[ctypes.addressof(string_buffer)])
          _safe_call(_LIB.LGBM_BoosterSaveModelToString(
              self.handle,
              ctypes.c_int(start_iteration),
              ctypes.c_int(num_iteration),
              ctypes.c_int64(buffer_len),
              ctypes.byref(tmp_out_len),
              ptr_string_buffer))
          actual_len = tmp_out_len.value
          # if buffer length is not long enough, re-allocate a buffer
          if actual_len > buffer_len:
              string_buffer = ctypes.create_string_buffer(actual_len)
              ptr_string_buffer = ctypes.c_char_p(*[ctypes.addressof(string_buffer)])
              _safe_call(_LIB.LGBM_BoosterSaveModelToString(
                  self.handle,
                  ctypes.c_int(start_iteration),
                  ctypes.c_int(num_iteration),
                  ctypes.c_int64(actual_len),
                  ctypes.byref(tmp_out_len),
                  ptr_string_buffer))
          ret = string_buffer.value.decode()
          ret += _dump_pandas_categorical(self.pandas_categorical)
          return ret
docs: Save Booster to string.
  
          Parameters
          ----------
          num_iteration : int or None, optional (default=None)
              Index of the iteration that should be saved.
              If None, if the best iteration exists, it is saved; otherwise, all iterations are saved.
              If <= 0, all iterations are saved.
          start_iteration : int, optional (default=0)
              Start index of the iteration that should be saved.
  
          Returns
          -------
          str_repr : string
              String representation of Booster.