code: def save_var_collection(
      file: Union[str, IO[BinaryIO]], vc: VarCollection
  ):
      """Saves variables collection into file.
  
      Args:
          file: filename or python file handle of the file where variables will be saved.
          vc: variables collection which will be saved into file.
      """
      do_close = isinstance(file, str)
      if do_close:
          filename, file = file, open(
              file + ".tmp", "wb"
          )  # Save to a temporary in case the job is killed while saving.
      data, names, seen, replicated = {}, [], set(), []
      for k, v in vc.items():
          if isinstance(v, TrainRef):
              v = v.ref
          if id(v) not in seen:
              names.append(k)
              data[str(len(data))] = v.value
              seen.add(id(v))
      if replicated:
          print(
              "Warning: When saving VarCollection, some variables were replicated on multiple devices."
          )
          print(
              "         While it is valid, in most use cases it is more disk efficient to save variables outside of "
          )
          print("         vars().replicate().")
  
      def _disabled_seek(*_):
          raise AttributeError("seek() is disabled on this object.")
  
      _old_seek = getattr(file, "seek")
      setattr(file, "seek", _disabled_seek)
      np.savez(file, names=np.array(names), **data)
      setattr(file, "seek", _old_seek)
      if do_close:
          file.close()
          os.rename(filename + ".tmp", filename)
  
file_path: objax/objax/io/ops.py
imports: import collections
  import os
  from typing import IO, BinaryIO, Union, Optional
  import jax.numpy
  import numpy
  from objax.util import Renamer
  from objax.variable import TrainRef, VarCollection
label_desc: Use image node_id 2 for calling a global function with example usage: save_var_collection(file, vc) without return types