docs: def observer(names_or_instance, names=None, func=None, change_only=False):
      """Specify a callback function that will fire on Property value change
  
      Observer functions on a HasProperties class fire after the observed
      Property or Properties have been changed (unlike validator functions
      that fire on set before the value is changed).
  
      You can use this method as a decorator inside a HasProperties class
  
      .. code::
  
          @properties.observer('variable_name')
          def callback_function(self, change):
              print(change)
  
      or you can use it to register a function to a single HasProperties
      instance
  
      .. code::
  
          properties.observer(my_has_props, 'variable_name', callback_function)
  
      The variable name must refer to a Property name on the HasProperties
      class. A list of Property names may also be used; the same
      callback function will fire when any of these Properties change. Also,
      :class:`properties.everything <properties.utils.Sentinel>` may be
      specified instead of the variable name. In that case, the callback
      function will fire when any Property changes.
  
      The callback function must take two arguments. The first is the
      HasProperties instance; the second is the change notification dictionary.
      This dictionary contains:
  
      * 'name' - the name of the changed Property
      * 'previous' - the value of the Property prior to change (this will be
        :code:`properties.undefined` if the value was not previously set)
      * 'value' - the new value of the Property (this will be
        :code:`properties.undefined` if the value is deleted)
      * 'mode' - the mode of the change; for observers, this is either
        'observe_set' or 'observe_change'
  
      Finally, the keyword argument **change_only** may be specified as a
      boolean. If False (the default), the callback function will fire any
      time the Property is set. If True, the callback function will only fire
      if the new value is different than the previous value, determined by
      the :code:`Property.equal` method.
      """
  
      mode = 'observe_change' if change_only else 'observe_set'
  
      if names is None and func is None:
          return Observer(names_or_instance, mode)
      obs = Observer(names, mode)(func)
      _set_listener(names_or_instance, obs)
      return obs