<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def on_attribute(self, attr_name, *args, **kwargs):
 """ Decorator for parameter listeners. .. note:: There is no way to remove a listener added with this decorator. Use :py:func:`add_attribute_listener` if you need to be able to remove the :py:func:`listener <remove_attribute_listener>`. The callback function is invoked only when the parameter changes. The callback arguments are: * ``self`` - the associated :py:class:`Parameters`. * ``attr_name`` - the parameter name. This can be used to infer which parameter has triggered if the same callback is used for watching multiple parameters. * ``msg`` - the new parameter value (so you don't need to re-query the vehicle object). The code fragment below shows how to get callbacks for the ``THR_MIN`` parameter: .. code:: python @vehicle.parameters.on_attribute('THR_MIN') def decorated_thr_min_callback(self, attr_name, value):
 print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) See :ref:`vehicle_state_observing_parameters` for more information. :param String attr_name: The name of the parameter to watch (or '*' to watch all parameters). :param args: The callback to invoke when a change in the parameter is detected. """

        attr_name = attr_name.upper()
        return super(Parameters, self).on_attribute(attr_name, *args, **kwargs)