code: def json_attributes(self, vfuncs=None):
          
  
          vfuncs = vfuncs or []
  
          js = {'global': {}}
  
          for k in self.ncattrs():
              js['global'][k] = self.getncattr(k)
  
          for varname, var in self.variables.items():
              js[varname] = {}
              for k in var.ncattrs():
                  z = var.getncattr(k)
                  try:
                      assert not np.isnan(z).all()
                      js[varname][k] = z
                  except AssertionError:
                      js[varname][k] = None
                  except TypeError:
                      js[varname][k] = z
  
              for vf in vfuncs:
                  try:
                      js[varname].update(vfuncs(var))
                  except BaseException:
                      logger.exception("Could not apply custom variable attribue function")
  
          return json.loads(json.dumps(js, cls=BasicNumpyEncoder))
docs: vfuncs can be any callable that accepts a single argument, the
          Variable object, and returns a dictionary of new attributes to
          set. These will overwrite existing attributes