def set_param(self_, *args, **kwargs):
    """
        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.
        """
    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()
