class_docstr: 定制给 :class:`~fastNLP.core.dataloaders.MixDataLoader` 的 ``BatchSampler``，其功能是将传入的 ``datasets`` 按顺序采样并返回 index，
  只有上一个 dataset 处理结束后才会处理下一个。
class_docstr_tok: ["\u5b9a\u5236\u7ed9",":","class",":","`","~fastNLP.core.dataloaders.MixDataLoader","`","\u7684","``","BatchSampler","``","\uff0c\u5176\u529f\u80fd\u662f\u5c06\u4f20\u5165\u7684","``","datasets","``","\u6309\u987a\u5e8f\u91c7\u6837\u5e76\u8fd4\u56de","index\uff0c","\u53ea\u6709\u4e0a\u4e00\u4e2a","dataset","\u5904\u7406\u7ed3\u675f\u540e\u624d\u4f1a\u5904\u7406\u4e0b\u4e00\u4e2a\u3002"]
docstr: 按照 ``dataset`` 的顺序采样，打包成一个 batch 后返回。
  
  :return:
docstr_tok: ["\u6309\u7167","``","dataset","``","\u7684\u987a\u5e8f\u91c7\u6837\uff0c\u6253\u5305\u6210\u4e00\u4e2a","batch","\u540e\u8fd4\u56de\u3002",":","return",":"]
code: def __iter__(self) -> Iterable[List[int]]:
      """
      按照 ``dataset`` 的顺序采样，打包成一个 batch 后返回。
  
      :return:
      """
      # sampler为str， 此时为单机多卡或者单机，可以实现rand随机化
      if isinstance(self.sampler, str):
          if self.sampler == "seq":
              self.sampler = {}
              for name, per_ds in self.datasets.items():
                  if self.word_size >= 0 and self.rank >= 0:
                      self.sampler[name] = InnerSampler(
                          list(range(len(per_ds)))[
                              self.rank :: self.word_size
                          ]
                      )
                  else:
                      self.sampler[name] = InnerSampler(
                          list(range(len(per_ds)))
                      )
          elif self.sampler == "rand":
              self.sampler = {}
              for name, per_ds in self.datasets.items():
                  g = torch.Generator()
                  g.manual_seed(self.epoch)
                  indices = torch.randperm(
                      len(per_ds), generator=g
                  ).tolist()
                  if self.word_size >= 0 and self.rank >= 0:
                      self.sampler[name] = InnerSampler(
                          indices[self.rank :: self.word_size]
                      )
                  else:
                      self.sampler[name] = InnerSampler(indices)
  
          # 根据给定的 ds_ratio 算真正需要处理数据集
          if isinstance(self.sampler, Dict):
              if self.ds_ratio is None:
                  sampler_lens = [
                      len(spl) for _, spl in self.sampler.items()
                  ]
  
              elif self.ds_ratio == "pad_to_most":
                  sampler_len = sum([1 for _ in self.sampler.keys()])
                  sampler_lens = [
                      max(len(spl) for _, spl in self.sampler.items())
                  ] * sampler_len
  
              elif self.ds_ratio == "truncate_to_least":
                  sampler_len = sum([1 for _ in self.sampler.keys()])
                  sampler_lens = [
                      min(len(spl) for _, spl in self.sampler.items())
                  ] * sampler_len
  
              elif isinstance(self.ds_ratio, Dict):
                  if not all(item >= 0 for item in self.ds_ratio):
                      raise ValueError(
                          "batch_size should be a positive integer value, "
                          "but got ds_ratio={}".format(self.ds_ratio)
                      )
                  sampler_lens = [
                      int(len(spl) * self.ds_ratio[name])
                      for name, spl in self.sampler.items()
                  ]
              else:
                  raise ValueError(
                      f"{self.ds_ratio} must be pad_to_least or truncate_to_least or None or List"
                  )
              total_lens = sum(sampler_lens)
          else:
              raise ValueError("datasets must be dict or list")
          # 初始化参数
          sampler_index = [sampler_lens[0]]
          for idx in sampler_lens[1:]:
              temp = sampler_index[-1]
              sampler_index.append(temp + idx)
          self.num_samplers = sampler_index
          self.len_samplers = total_lens
  
      batch_idx, total_index, samplers = (
          [],
          list(range(self.len_samplers)),
          [],
      )
      start_idx = 0
  
      # （特定数据集需要长度，特定数据集sampler, 特定数据集的基址， 特定sampler的下标）
      for idx, (name, spl) in enumerate(self.sampler.items()):
          end_idx = len(spl)
          samplers.append((iter(spl), name, start_idx))
          start_idx += end_idx
      # if self.word_size > 0 and self.rank >= 0:
      #     sampler_base_index = [0] + [len(spl) * self.word_size for _, spl in self.sampler.items()][:-1]
      # else:
      #     sampler_base_index = [0] + [len(spl) for _, spl in self.sampler.items()][:-1]
      #
      # samplers = [(iter(spl), name, sampler_base_index[idx])
      #             for idx, (name, spl) in enumerate(self.sampler.items())]
      for idx in total_index:
          ds_index = np.searchsorted(
              self.num_samplers, idx, side="right"
          )
  
          spl, name, base_index = samplers[ds_index]
          try:
              batch_idx.append(next(spl) + base_index)
          except StopIteration:
              # 重新初始化一个新的sampler，因为不可能为空，故一定不会出现stopIteration
              spl = iter(self.sampler[name])
              batch_idx.append(next(spl) + base_index)
              samplers[ds_index] = (spl, name, base_index)
          if len(batch_idx) == self.batch_size:
              yield batch_idx
              batch_idx = []
          # 当前数据集采样完，需要及时处理最后一个batch
          if self.num_samplers[ds_index] == (idx + 1):
              if len(batch_idx) > 0 and not self.drop_last:
                  yield batch_idx
              batch_idx = []
  
imports: import array
  import numpy
  from typing import Union, List, Iterable, Dict
  from fastNLP.envs.imports import _NEED_IMPORT_TORCH
label_desc: Use image node_id 2 for calling the MixSequentialSampler obj's underlying member method code with example usage: obj.__iter__() without return types