Using Traitlets
===============

.. currentmodule:: traitlets

Any class with trait attributes must inherit from :class:`HasTraits`.

.. autoclass:: HasTraits

   .. automethod:: has_trait

   .. automethod:: trait_names

   .. automethod:: class_trait_names

   .. automethod:: traits

   .. automethod:: class_traits

   .. automethod:: trait_metadata

   .. automethod:: add_traits

You then declare the trait attributes on the class like this::

    from traitlets import HasTraits, Int, Unicode

    class Requester(HasTraits):
        url = Unicode()
        timeout = Int(30)  # 30 will be the default value

For the available trait types and the arguments you can give them, see
:doc:`trait_types`.

Dynamic default values
----------------------

To calculate a default value dynamically, decorate a method of your class with
`@default({traitname})`. This method will be called on the instance, and should
return the default value. For example::

    import getpass

    class Identity(HasTraits):
        username = Unicode()

        @default('username')
        def _username_default(self):
            return getpass.getuser()

Callbacks when trait attributes change
--------------------------------------

To do something when a trait attribute is changed, decorate a method with :func:`traitlets.observe`.
The method will be called with a single argument, a dictionary of the form::

    {
      'owner': object, # The HasTraits instance
      'new': 6, # The new value
      'old': 5, # The old value
      'name': "foo", # The name of the changed trait
      'type': 'change', # The event type of the notification, usually 'change'
    }

For example::

    from traitlets import HasTraits, Integer, observe
    
    class TraitletsExample(HasTraits):
        num = Integer(5, help="a number").tag(config=True)
        
        @observe('num')
        def _num_changed(self, change):
            print("{name} changed from {old} to {new}".format(**change))


.. versionchanged:: 4.1

    The ``_{trait}_changed`` magic method-name approach is deprecated.

You can also add callbacks to a trait dynamically:

.. automethod:: HasTraits.observe

.. note::

    If a trait attribute with a dynamic default value has another value set
    before it is used, the default will not be calculated.
    Any callbacks on that trait will will fire, and *old_value* will be ``None``.
