class_docstr: Similar to :class:`MultiProcessMapDataZMQ`, except that this DataFlow
  also does batching in parallel in the worker processes.
  Therefore it can be helpful if you wish to hide the latency of batching.
  
  When `nr_proc==1`, the behavior of this class is identical to
  `BatchData(MapData(ds, map_func), batch_size)`.
  
  When `nr_proc>1`, the datapoints may be grouped in arbitrary order,
  or grouped with datapoints from a different pass of the given dataflow.
code: def __iter__(self):
      with self._guard, _zmq_catch_error(type(self).__name__):
          while True:
              yield loads(self.socket.recv(copy=False))
  
imports: import copy
  import ctypes
  import multiprocessing
  import numpy
  import threading
  import zmq
  from six.moves import queue
  from ..utils.concurrency import StoppableThread, enable_death_signal
  from ..utils.serialize import dumps_once, loads_once
  from .base import DataFlow, DataFlowReentrantGuard, ProxyDataFlow
  from .common import RepeatedData, BatchData
  from .parallel import _bind_guard, _get_pipe_name, _MultiProcessZMQDataFlow, _repeat_iter, _zmq_catch_error
label_desc: Use image node_id 3 for calling the MultiProcessMapAndBatchDataZMQ obj's underlying member method code with example usage: obj.__iter__() without return types