class_docstr: DataIterator
  Collect data from `data_source` and yields bunch of data.
  
  Args:
      data_source (:py:class:`DataSource <nnabla.utils.data_source.DataSource>`):
           Instance of DataSource class witch provides data for this class.
      batch_size (int): Size of data unit.
      rng (None or :obj:`numpy.random.RandomState`): Numpy random number
          generator.
      use_thread (bool): If ``use_thread`` is set to True, iterator will use another
          thread to fetch data. If ``use_thread`` is set to False, iterator will use
          current thread to fetch data.
      epoch_begin_callbacks (list of functions): An item is a function
          which takes an epoch index as a argument. These are called
          at the beginning of an epoch.
      epoch_end_callbacks (list of functions): An item is a function
          which takes an epoch index as a argument. These are called
          at the end of an epoch.
      stop_exhausted (bool): If ``stop_exhausted`` is set to False, iterator will be reset
          so that iteration can be continued. If ``stop_exhausted`` is set to True, iterator
          will raise StopIteration to stop the loop.
code: def __init__(
      self,
      data_source,
      batch_size,
      rng=None,
      use_thread=True,
      epoch_begin_callbacks=[],
      epoch_end_callbacks=[],
      stop_exhausted=False,
  ):
      logger.info("Using DataIterator")
      if rng is None:
          rng = numpy.random.RandomState(313)
      self._stop_exhausted = stop_exhausted
      self._rng = rng
      self._shape = None  # Only use with padding
      self._data_position = 0  # Only use with padding
  
      self._data_source = data_source
      # place holder for shuffle is enabled or not at starting time.
      self._shuffle = self._data_source.shuffle
  
      self._variables = data_source.variables
      self._num_of_variables = len(data_source.variables)
      self._batch_size = batch_size
  
      self._epoch_end_callbacks = list(epoch_end_callbacks)
      self._epoch_begin_callbacks = list(epoch_begin_callbacks)
  
      self._size = data_source.size
  
      self._n_reset = 0
      self._queue = queue.Queue()
      self._reset()
      self._current_epoch = 0
  
      self._use_thread = use_thread
      if self._use_thread:
          self._next_thread = threading.Thread(target=self._next)
          self._next_thread.start()
  
      self._closed = False
      atexit.register(self.close)
  
imports: import atexit
  import threading
  import queue
  import numpy
  import six
  from nnabla.logger import logger
  from .data_source import DataSourceWithFileCache
  from .data_source import DataSourceWithMemoryCache
  from .data_source import SlicedDataSource
  from .data_source_implements import CacheDataSource
  from .data_source_implements import ConcatDataSource
  from .data_source_implements import CsvDataSource
  from .data_source_implements import SimpleDataSource
label_desc: Use image node_id 1 to create a new DataIterator object from inherited base classes: object with example: obj = DataIterator(data_source, batch_size, rng, use_thread, epoch_begin_callbacks, epoch_end_callbacks, stop_exhausted)