Traitlets#
Traitlets is a tool that allows to make python objects that, automatically check types, autamatically change values of attributes and implement “on change” callbacks.
import traitlets
Observation#
“Observing” is one of the main features of the HasTraits
objects. You can set a method to be called when something changes in the instance with the observe
method. If you don’t need this callback anymore just use the unobserve
method.
The following cell creates a has_traits
object that has the my_trait
trait and attaches something
function to be called when any attribute in the has_traits
changes.
class ItHasTratis(traitlets.HasTraits):
my_trait = traitlets.Int()
has_traits = ItHasTratis()
def something(change):
print("Trait value changed!")
has_traits.observe(something)
So in case to has_tratis.my_trait
got a new value - code of the something
is executed.
has_traits.my_trait = 1
Trait value changed!
The following cell unobserve
callback from the has_trats
object.
has_traits.unobserve(something)
has_traits.my_trait = 2
As a result, there is no output assumed by something
in the output.
Change#
Any function that you assign to be a callback must have a to have one parameter - this is an for argument that describes the change that triggered the callback.
The next cell defines HasTraits
, which stores the change
it received in the global variable test
- so it’s possible to study this object from the global environment.
test: object
class ItHasTratis(traitlets.HasTraits):
my_trait = traitlets.Int()
@traitlets.observe(traitlets.All)
def method(self, change):
global test
test = change
has_traits = ItHasTratis()
has_traits.my_trait = 1
The next cell shows the type of the object.
type(test)
traitlets.utils.bunch.Bunch
Actually, it’s a relatively simple dictionary that describes change.
test
{'name': 'my_trait',
'old': 0,
'new': 1,
'owner': <__main__.ItHasTratis at 0x7ddb005f7b30>,
'type': 'change'}
Configurable#
Configurable
is a special object that allows objects to be created from a configuration file defined elsewhere. In particular, it could be a simple python file that has traitlets.config.Config
defined in it.
The following cell defines Configurable
, which we’ll use as an example.
class MyConfigurable(traitlets.config.Configurable):
name = traitlets.Unicode("DefaultName", config=True)
count = traitlets.Int(5, config=True)
The following cell defines config - so it contains default values for attributes of the MyConfigurable
instance.
config = traitlets.config.Config()
config.MyConfigurable.name = "Alice"
config.MyConfigurable.count = 42
The following code creates MyConfigurable
with the previously defined config - the corresponding attributes take the values as defined in the config.
my_configurable = MyConfigurable(config=config)
print(my_configurable.name, my_configurable.count)
Alice 42
Application#
Application is a class that implements functionality that needs to be shared by the entire application - more specificaly, it manages global parameters that are loaded from command line arguments.
The IPKernel backend itself uses this class - so it is autamatically created for each IPython notebook.
The Application.instance
method returns the current instance of the Application
or creates a new one if it’s needed. The following cell shows that Application.instance
executed from IPython kernel returns application that implements IPython backend.
from traitlets.config import Application
Application.instance()
<ipykernel.kernelapp.IPKernelApp at 0x7e6f93bf98e0>
To actually create a new instance for experiments, it must be run in the separate python object. The next cell shows an option to run it.
%%writefile /tmp/application.py
from traitlets.config import Application
print(Application.instance())
Writing /tmp/application.py
!python3 /tmp/application.py
<traitlets.config.application.Application object at 0x748f6a9f7560>
Note there is a hack - set Applicaiton._instance = None
it will make Applicaiton
to think it isn’t initialized. Obviously never use it in any production level solutions, but for experimenting purposes it’s ok.
The following cell resets Application
and shows that from that point Applicaiton.instance()
returns the Application
instance.
Application._instance = None
Application.instance()
<traitlets.config.application.Application at 0x7e6f8c44a5d0>