code: def replace_sampler(dataloader: "DataLoader", sampler):
      r"""
      替换 sampler （初始化一个新的 dataloader 的逻辑在于）：
  
      用户可能继承了 dataloader，定制了自己的 dataloader 类，这也是我们为什么先 `inspect.signature(dataloader)` 而不是直接
      `inspect.signature(DataLoader)` 的原因，因此同时注意到我们在外层重新初始化一个 dataloader 时也是使用的用户传进来的 dataloader
      的类，而不是直接的 DataLoader；
  
      如果需要定制自己的 dataloader，保证以下两点：
  
          1. 在 __init__ 方法中加入 **kwargs，这是为了方便我们将 sampler 插入到具体的 DataLoader 的构造中；
          2. 在 __init__ 方法中出现的参数，请务必挂为同样名字的实例属性，例如 self.one_arg_name = one_arg_name，这是因为我们只能通过属性
          来获取实际的参数的值；
  
      """
  
      # 拿到实例属性；
      instance_attrs = {
          k: v
          for k, v in vars(dataloader).items()
          if not k.startswith("_")
      }
  
      # 'multiprocessing_context' 是 user-defined function;
      if (
          getattr(dataloader, "multiprocessing_context", None)
          is not None
      ):
          instance_attrs[
              "multiprocessing_context"
          ] = dataloader.multiprocessing_context
  
      # 拿到 dataloader '__init__' 函数的默认函数签名；
      init_params = dict(
          inspect.signature(dataloader.__init__).parameters
      )
  
      # 防止用户的 DataLoader 是继承了 pytorch 的 DataLoader，然后还是使用了 **kwargs 的方式对父类传参数
      has_variadic_kwargs = any(
          v.kind is v.VAR_KEYWORD for k, v in init_params.items()
      )
      if has_variadic_kwargs and isinstance(dataloader, DataLoader):
          # 防止用户写入了 super().__init__(**kwargs)
          for key, value in dict(
              inspect.signature(DataLoader.__init__).parameters
          ).items():
              if key not in init_params and key != "self":
                  init_params[key] = value
  
      # 如果初始化dataloader所使用的参数不是默认值，那么我们需要将其记录下来用于重新初始化时设置；
      non_default_params = {
          name
          for name, p in init_params.items()
          if name in instance_attrs
          and p.default != instance_attrs[name]
      }
      # add `dataset` as it might have been replaced with `*args`
      non_default_params.add("dataset")
  
      reconstruct_args = {
          k: v
          for k, v in instance_attrs.items()
          if k in non_default_params
      }
      if isinstance(dataloader, DataLoader):
          reconstruct_args.update(
              {
                  "sampler": sampler,
                  "shuffle": False,
                  "batch_sampler": None,
              }
          )
  
      batch_sampler = getattr(dataloader, "batch_sampler")
      if batch_sampler is not None and isinstance(
          batch_sampler, ReproducibleBatchSampler
      ):
          raise RuntimeError(
              "It should not be running here, please report a bug to us."
          )
  
      required_args = {
          p.name
          for p in init_params.values()
          if p.kind in (p.POSITIONAL_ONLY, p.POSITIONAL_OR_KEYWORD)
          and p.default is p.empty
          and p.name not in reconstruct_args
      }
  
      # 在 attribute 中没有找到这些参数，导致了没有办法重新初始化
      if required_args:
          required_args = sorted(required_args)
          dataloader_self_name = dataloader.__class__.__name__
          raise Exception(
              f"Need to inject arguments {required_args} into the __init__ of `{dataloader_self_name}`. "
              f"But they are not found in the attribute of `{dataloader_self_name}`, fastNLP cannot determine its "
              f"value when try to reinitialize `{dataloader_self_name}`, please add `{required_args}` to be "
              f"`{dataloader_self_name}`'s attribute."
          )
  
      # 这种错误针对的是传入的 dataloader 不是直接的 DataLoader，而是定制了 DataLoader，但是 __init__ 中没有 **kwargs；
      if not has_variadic_kwargs:
          # the dataloader signature does not allow keyword arguments that need to be passed
          missing_kwargs = reconstruct_args.keys() - init_params.keys()
          if missing_kwargs:
              missing_kwargs = sorted(missing_kwargs)
              dataloader_self_name = dataloader.__class__.__name__
              raise Exception(
                  f"The parameter:{missing_kwargs} needed to reinitialize `{dataloader_self_name}` is not found."
              )
          # 如果没有kwargs，则保证一下只传入需要的参数
          if not isinstance(dataloader, DataLoader):
              reconstruct_args = {
                  key: value
                  for key, value in reconstruct_args.items()
                  if key in init_params
              }
  
      return type(dataloader)(**reconstruct_args)
  
imports: import os
  from typing import Any, Dict, Optional, Union
  from enum import IntEnum
  import contextlib
  import random
  import numpy
  import inspect
  from fastNLP.envs.imports import _NEED_IMPORT_TORCH
  from fastNLP.envs.utils import get_global_seed
  from fastNLP.envs import get_global_rank, FASTNLP_BACKEND_LAUNCH, FASTNLP_GLOBAL_SEED
  from fastNLP.core.samplers import re_instantiate_sampler, ReproducibleBatchSampler, ReproducibleSampler
  from fastNLP.core.utils import auto_param_call, apply_to_collection
  from fastNLP.core.log import logger
label_desc: Use image node_id 3 for calling a global function with example usage: replace_sampler(dataloader, sampler) and returns: type