order.unique¶
Classes that define unique objects and the index to store them.
Contents
Class UniqueObject¶
- class UniqueObject(name, id, context=None)¶
Bases:
UniqueObject
An unique object defined by a name and an id. The purpose of this class is to provide a simple interface for objects that
are used programatically and should therefore have a unique, human-readable name, and
have a unique identifier that can be saved to files, such as (e.g.) ROOT trees.
Both, name and id should have unique values within a certain uniqueness context. This context defaults to either the current one as set by
uniqueness_context()
, the default_context of this class, or, whem empty, the lower-case class name. Seeget_default_context()
for more info.Arguments
name, id and context initialize the same-named attributes.
Copy behavior
When an inheriting class inherits also from
CopyMixin
certain copy rules apply for the name, id and context attributes as duplicate names or ids within the same context would directly cause an exception to be thrown (which is the desired behavior, see examples below). Two ways are in general recommended to copy a unique object:import order as od class MyClass(od.UniqueObject, od.CopyMixin): pass orig = MyClass("foo", 1) # 1. use the same context, explicitely change name and id copy = orig.copy(name="bar", id=2) # 2. use a different context, optionally set different name or id with od.unqiueness_context("other"): copy = orig.copy() copy2 = orig.copy(name="baz")
Example
import order as od foo = od.UniqueObject("foo", 1) print(foo.name) # -> "foo" print(foo.id) # -> 1 # name and id must be strictly string and integer types, respectively od.UniqueObject(123, 1) # -> TypeError: invalid name: 123 UniqueObject("foo", "mystring") # -> TypeError: invalid id: mystring # the name "foo" and the id 1 can no longer be used # (at least not within the same uniqueness context, which is the default one when not set) bar = UniqueObject("foo", 2) # -> DuplicateNameException: 'order.unique.UniqueObject' object with name 'foo' already # exists in the uniqueness context 'uniqueobject' bar = UniqueObject("bar", 1) # -> DuplicateIdException: 'order.unique.UniqueObject' object with id '1' already exists in # the uniqueness context 'uniqueobject' # everything is fine when an other context is provided bar = UniqueObject("bar", 1, context="myNewContext") # works! # unique objects can als be compared by name and id foo == 1 # -> True bar == "bar" # -> True foo == bar # -> False # automatically use the next highest possible id obj = UniqueObject("baz", id=UniqueObject.AUTO_ID) obj.id # -> 2 # 1 is the highest used id in the default context, see above
Members
- classattributedefault_context¶
- type: arbitrary (hashable)
The default context of uniqueness when none is given in the instance constructor. Two instances are only allowed to have the same name or the same id if their classes have different contexts. This member is not inherited when creating a sub-class.
- classattributecls_name_singular¶
- type: str
The name of the unique object class in singular form, e.g. for producing automatic messages.
- classattributecls_name_plural¶
- type: str
The name of the unique object class in plural form, e.g. for producing automatic messages.
- context¶
- type: arbitrary (hashable)
The uniqueness context of this instance.
- name¶
- type: str
- read-only
The unique name.
- id¶
- type: int
- read-only
The unique id.
- classmethod get_instance(obj, default=no_default, context=None)¶
Returns an object that was instantiated by this class before. obj might be a name, id, or an instance of cls. If default is given, it is used as the default return value if no such object was found. Otherwise, an error is raised. context defaults to the
default_context
of this class.
- classmethod auto_id(name, context)¶
Method to create an automatic id for instances that are created with
id="+"
. The default recipe ismax(ids) + 1
.
Class UniqueObjectIndex¶
- class UniqueObjectIndex(cls, objects=None, default_context=None)¶
Bases:
CopyMixin
Index of
UniqueObject
instances for faster lookup by either name or id. The instances are stored for different uniqueness context, so most methods have a context argument which usually defaults to the return value ofUniqueObject.get_default_context()
.Arguments
cls must be a subclass of
UniqueObject
, which is used for type validation when a new object is added to the index. The default_context is used in case no context argument is set in most methods of this index object. It defaults to the return value of the cls’UniqueObject.get_default_context()
.Example
import order as od idx = od.UniqueObjectIndex() foo = idx.add("foo", 1) bar = idx.add("bar", 2) len(idx) # -> 2 idx.names() # -> ["foo", "bar"] idx.ids() # -> [1, 2] idx.get(1) == foo # -> True # add objects for an other uniqueness context # note: for the default context, the redundant use of the id 1 would have caused an error! baz = idx.add("baz", 1, context="other") len(idx) # -> 3 # idx.len() (with a context argument) returns the number of objects contained with the # default context idx.len() # -> 2 idx.len(context="other") # -> 1 # get ids of objects for all contexts (which might contain duplicates) idx.ids(context=all) # -> [1, 2, 1]
Members
- classattributeALL¶
The flag that denotes that all contexts should be tranversed in methods that accept a context argument. It defaults to the built-in function
all
.
- cls¶
- type: class
- read-only
Class of objects hold by this index.
- default_context¶
- type: string
The default context that is used when no context argument is provided in most methods.
- n¶
- type: DotAccessProxy
- read-only
An object that provides simple attribute access to contained objects via name in the default context.
- ALL()¶
Return True if bool(x) is True for all values x in the iterable.
If the iterable is empty, return True.
- len(context=None)¶
Returns the length of the index stored for context. When None, the default_context is used. When context is all, the sum of lengths of all indices is returned, which is equivalent to
__len__()
.
- contexts()¶
Returns a list of all contexts for whom indices are stored.
- names(context=None)¶
Returns the names of the contained objects in the index stored for context. When None, the default_context is used. When context is all, a list of tuples (name, context) are returned with names from all indices. Note that the returned context refers to the one the object is stored in, rather than the uniqueness context of the object itself.
- ids(context=None)¶
Returns the names of the contained objects in the index stored for context. When None, the default_context is used. When context is all, a list of tuples (id, context) are returned with ids from all indices. Note that the returned context refers to the one the object is stored in, rather than the uniqueness context of the object itself.
- keys(context=None)¶
Returns pairs containing name and id of the currently contained objects in the index stored for context. When None, the default_context is used. When context is all, tuples (name, id, context) are returned with objects from all indices. Note that the returned context refers to the one the object is stored in, rather than the uniqueness context of the object itself.
- values(context=None)¶
Returns all contained objects in the index stored for context. When None, the default_context is used. When context is all, tuples (value, context) are returned with objects from all indices. Note that the returned context refers to the one the object is stored in, rather than the uniqueness context of the object itself.
- items(context=None)¶
Returns a list of (nested) tuples ((name, id), value) of all objects in the index stored for context. When context is all, tuples ((name, id), value, context) are returned with objects from all indices. Note that the returned context refers to the one the object is stored in, rather than the uniqueness context of the object itself.
- add(*args, **kwargs)¶
Adds a new object to the index for a certain context. When the first arg is not an instance of cls, all args and kwargs are passed to the cls constructor to create a new object. In this case, the kwargs may contain index_context to define the context if the index in which the newly created object should be stored. When not set, default_context is used. Otherwise, when the first arg is already an object and to be added, the context is either index_context or contex. The former has priority for consistency with the case described above. In both cases the added object is returned.
- extend(objs, context=None)¶
Adds multiple new objects to the index for context. All elements of the sequence objs are forwarded to
add()
and returns the added objects in a list. When an object is a dictionary or a tuple, it is expanded for the invocation ofadd()
. When context is None, the default_context is used.
- get(obj, default=no_default, context=None)¶
Returns an object that is stored in the index for context. obj might be a name, id, or an instance of cls. If default is given, it is used as the default return value if no such object could be found. Otherwise, an error is raised. When context is None, the default_context is used.
- get_first(default=no_default, context=None)¶
Returns the first object that is stored in the index for context. If default is given, it is used as the default return value if no object could be found. Otherwise, an error is raised. When context is None, the default_context is used.
- get_last(default=no_default, context=None)¶
Returns the last object that is stored in the index for context. If default is given, it is used as the default return value if no object could be found. Otherwise, an error is raised. When context is None, the default_context is used.
- has(obj, context=None)¶
Checks if an object is contained in the index for context. obj might be a name, id, or an instance of the wrapped cls. When context is None, the default_context is used.
- index(obj, context=None)¶
Returns the position of an object in the index for context. When context is None, the default_context is used. obj might be a name, id, or an instance of cls. When the object is not found in the index, an error is raised.
- remove(obj, context=None, silent=False)¶
Removes an object from the index for context. obj might be a name, id, or an instance of cls. Returns the removed object. Unless silent is True, an error is raised if the object could not be found. When context is None, the default_context is used.
- clear(context=None)¶
Clears the index for context by removing all elements. When None, the default_context is used. When context is all, the indices for all contexts are cleared.
Class UniqueObjectMeta¶
- class UniqueObjectMeta(class_name, bases, class_dict)¶
Bases:
type
Meta class definition that adds an instance cache to every class inheriting from
UniqueObject
.
Function uniqueness_context¶
- uniqueness_context(context)¶
Adds the uniqueness context on top of the list of the current contexts, which is priotized in the
UniqueObject
constructor when no context is configured.obj = UniqueObject("myObj", 1, context="myContext") obj.context # -> "myContext" with uniqueness_context("otherContext"): obj2 = UniqueObject("otherObj", 2) obj2.context # -> "otherContext"
Decorator unique_tree¶
- unique_tree(cls=None, parents=1, deep_children=False, deep_parents=False, skip=None)¶
Decorator that adds attributes and methods to the decorated class to provide tree features, i.e., parent-child relations. Example:
@unique_tree() class MyNode(UniqueObject): cls_name_singular = "node" cls_name_plural = "nodes" default_context = "myclass" # now, MyNode has the following attributes and methods: # nodes, parent_nodes, # has_node(), has_parent_node(), # add_node(), add_parent_node(), # remove_node(), remove_parent_node(), # walk_nodes(), walk_parent_nodes(), # get_node(), get_parent_node(), # has_nodes, has_parent_nodes, # is_leaf_node, is_root_node c1 = MyNode("nodeA", 1) c2 = c1.add_node("nodeB", 2) c1.has_node(2) # -> True c2.has_parent_node("nodeA") # -> True c2.remove_parent_node(c1) c2.has_parent_node("nodeA") # -> False
cls denotes the type of instances the tree should hold and defaults to the decorated class itself. When parents is False, the additional features are reduced to provide only child relations. When parents is an integer, it is interpreted as the maximim number of parents a child can have. Negative numbers mean that an unlimited amount of parents is allowed. Additional convenience methods are added when parents is True or exactly 1. When deep_children (deep_parents) is True, get_* and has_* child (parent) methods will have recursive features. When skip is a sequence, it can contain names of attributes to skip that would normally be created.
A class can be decorated multiple times. Internally, the objects are stored in a separated
UniqueObjectIndex
instance per added tree functionality.Doc strings are automatically created.