Package: ood
para españolObserving Ordered DictionaryThe observing ordered dictionary is a datastructure for accessing child-elements by name or position. It is meant to be inherited (or composed: I inherit it in my applications, but it's almost composed given I override and rename every public method).Parent objects (Observer()) will register themselves with their child elements (Observed()), who can notify the parent object of changes to its (the child's) properties. The classes are combined by the classItem(Observer, Observed).It is well, if not chaotically, tested.NB: WhileObserver()supports iteration andlen(), indexing by[]is not supported yet.Basic Use:importoodo=ood.Observer(*items_to_add)o.add_items(*items_to_add)o.pop_items(*items_to_pop)# returns listo.get_items(*selectors)# returns listo.get_item(selector)# see Selectors section belowo.has_item(selector)o.reorder_all_items([selectors])o.move_items(*selectors,...)# must have one of before=, after=, position=, distance=Children must inheritclass Observed(), whose__init__(self, **kwargs)takes anameargument, and will supply methodsget_name()andset_name():importoodo=Observed(name="test")o.get_name()=="test"# Trueo.set_name("test2")o.get_name()=="test2"# TrueAlso supplied are other internal_functions()used in parent-child communication.SelectorsA primitiveselectoris either anint(the position of the child) or astr(the name of the child).There is also aclass Selector(), which is inherited by three other classes (two fromood.selectors) you can use:Classes 1, 2importoodimportood.selectorsass# Class 1:# Select which child precisely if children w/ same name are allowed.# Ordered by insertion.s.Name_I(child_namestr,child_indexint)# Class 2:# Select children which they themselves have specified children.s.Has_Child(selector)#Class 3:AllObservedare also selectors which specify to return themselves. Example:importoodchild=ood.Observed("A")not_child=ood.Observed("B")parent=ood.Observer(child)parent.has_item(child)# Trueparent.has_item("A")# Trueparent.has_item(0)# True, useless.parent.has_item(not_child)# Falseparent.has_item("B")# Falseparent.has_item(1)# FalseConfiguration Settings:ood.exceptionshasErrorLevel.IGNORE,ErrorLevel.WARNandErrorLevel.ERROR.Trueis alsoERRORandFalseisIGNORE.The default values are shown below, they can be overridden:importood.exceptionaserr# Do non-existing indices to get_item(s), pop_items produce errors or empty array (or None)?err.StrictIndexException.default_level=err.ErrorLevel.IGNORE# Can one child have multiple parents?err.MultiParentException=err.ErrorLevel.ERROR# WARN not possible# Can multiple children of one parent have the same name?err.NameConflictException=err.ErrorLevel.ERROR# WARN not possible# Do we warn or error if you add the same child twice?err.RedundantAddException=err.ErrorLevel.WARNExtendingIf you inhert Observer() or Item(), you can override class variables_typeand_child_type, exceptions generated will use those terms instead of "item" when raising exceptions.classRedNodes(ood.Item):_type="RedNode"_child_type="Node"def__init__(self,*args,**kwargs):_my_vars=kwargs.pop("key","default_value")# Popping is important! Don't pass weird stuff to ood!super().__init__(*args,**kwargs)...# Do whatever you wantdefget_node(self,selector,**kwargs):returnsuper().get_item(self,selector,**kwargs)...# etcAdding more observed variables:Children can call_notify_parents(parameter=..., old_parameter=...), where parameter would be the parameter that changes.
For example,set_name("new_name")calls_notify_parents(self, name="new_name", old_name="old_name").On the parent side, you must implemento._child_options(self,child,**kwargs)o._child_update(self,child,**kwargs)_child_options()shouldraisean exception, and the child should understand that the parameter change will not be accepted. (this is used in case the configuration is set that two children cannot have the same name).defset_name(self,name):old_name=self.get_name()self._name=nametry:_notify_parents(self,old_name=old_name,name=name)except:self._name=old_nameraiseException("Can't change name!")