code: def set_param(self_, *args,**kwargs):
          
          BATCH_WATCH = self_.self_or_cls.param._BATCH_WATCH
          self_.self_or_cls.param._BATCH_WATCH = True
          self_or_cls = self_.self_or_cls
          if args:
              if len(args) == 2 and not args[0] in kwargs and not kwargs:
                  kwargs[args[0]] = args[1]
              else:
                  self_.self_or_cls.param._BATCH_WATCH = False
                  raise ValueError("Invalid positional arguments for %s.set_param" %
                                   (self_or_cls.name))
  
          for (k, v) in kwargs.items():
              if k not in self_or_cls.param:
                  self_.self_or_cls.param._BATCH_WATCH = False
                  raise ValueError("'%s' is not a parameter of %s" % (k, self_or_cls.name))
              try:
                  setattr(self_or_cls, k, v)
              except:
                  self_.self_or_cls.param._BATCH_WATCH = False
                  raise
  
          self_.self_or_cls.param._BATCH_WATCH = BATCH_WATCH
          if not BATCH_WATCH:
              self_._batch_call_watchers()
docs: For each param=value keyword argument, sets the corresponding
          parameter of this object or class to the given value.
  
          For backwards compatibility, also accepts
          set_param("param",value) for a single parameter value using
          positional arguments, but the keyword interface is preferred
          because it is more compact and can set multiple values.