Persistent Container (base class to all of OOPS).
Nodes represent positions in a dictionary-like database. A tree structure
of nodes (like a tree structure of instances) is mirrored on the database
by using each node's path as its identifying key. An example of this is if
you have an node that you can reach in python by typing parent.node.child,
its path (stored in its __path__ attribute) is the tuple (node , child ).
The reason the path does not have the root object's key is that is was not
necessary for me to store it (and also it is currently impossible using
python's standard hooks to get that name).
If a node is bound (already has a parent node) and is assigned to a new
container node, a copy of it is made and that copy is bound instead.
Example:
>>> root = Node()
>>> print root.__path__
()
>>> root.subnode = Node() # bind Node instance to root
>>> print root.subnode.__path__
('subnode',)
>>> newnode = Node() # unbound
>>> print newnode.__path__
()
>>> root.subnode.anothernode = newnode # bind to root.subnode
>>> print root.subnode.anothernode.__path__
('subnode', 'anothernode')
>>> root.copynode = root.subnode
>>> print root.copynode.__path__, root.subnode.__path__
('copynode',) ('subnode',)
Node was not designed to be instantiated and used, but to be inherited from
to create your own persistent classes (two examples of which are Dict and
List).
Important attributes:
- __parent__
- weak reference to the parent node. When a node is
unbound, this returns None.
- __path__
- address of this Node in its filesystem. It is a tuple
of keys identifying each node inside its parent and
placed in order from the top-most node to the current
node. example: obj.subobj.newobj.__path__ is
(
subobj , newobj )
- __database__
- dictionary-like object used for persistent storage.
a repr()'d version of the node's path is used as
the node's database key.
NOTE* You will notice that I follow the general Python naming convention
for attributes that define behavior (__varname__). The reason for this is
I don't want those attributes to be out of reach for developers of
extension libraries, but at the same time I don't want developers that use
those libraries to be burdened with the implementation details of OOPS.
Methods
|
|
|
|
__bindto__
|
__bindto__ (
self,
database,
path=(),
parent=None,
)
Bind node to new location.
Recursively bind all subnodes to the new location & load persistent
runtime data.
This method is called by the parent node at binding time and also in
Node.__init__.
- path
- tuple representing the node's address in the database.
- database
- the database used to store the node's persistent
data.
- parent
- parent node.
OOPS behavior methods
|
|
__clear__
|
__clear__ ( self )
Recursively delete all persistent data under `self`.
This method does not actually do anything, but is there as a hook
for subclasses.
|
|
__copyfrom__
|
__copyfrom__ ( self, other )
Make `self` a copy of `other`.
This method does not actually do anything, but is there as a hook
for subclasses.
|
|
__delattr__
|
__delattr__ ( self, name )
Attribute deletion operator.
If the attribute identified by name is a node, all its data is
recursively deleted before finally removing it from the instance's
attribute dictionary.
If it is not a node, a regular attribute deletion is executed.
|
|
__init__
|
__init__ ( self, **keywords )
Constructor.
Optional keyword arguments:
- database
- initial database to.
- filename
- binds the node to this file. If the file doesn't
exist, it is created.
- datasource
- tuple of initial arguments to __bindto__.
- copyfrom
- initial argument to __copyfrom__.
|
|
__moveto__
|
__moveto__ (
self,
database,
path=(),
parent=None,
)
Move node to new location
Recursively move all subnodes to the new location.
This method is called by the parent node at binding time if the node
has data.
- path
- tuple representing the node's address in the database.
- database
- the database used to store the node's persistent
data.
- parent
- parent node.
|
|
__nonzero__
|
__nonzero__ ( self )
Test for emptiness.
If the node has row data (or a subnode has row data) the node is
nonzero.
|
|
__repr__
|
__repr__ ( self )
Representation of a Node instance.
Overloaded to provide an informative description of a Node instance.
|
|
__setattr__
|
__setattr__ (
self,
name,
value,
)
Attribute assignment operator.
If value is a node and unbound, it is bound to self. If it is nonzero
(not empty), it is moved to self. If it is bound, a copy of it is made
and that copy is either bound or moved depending on if the node is
empty or not.
If the attribute by that name is a node, value is assigned to the node
by calling its __setval__ method.
If neither value nor the attribute identified by name are nodes, then
it is a normal attribute assignment.
|
|
__setval__
|
__setval__ ( self, value )
Assign value to this node.
This method is not used by Node. It is meant to be overloaded by a
subclass (for example see List & Dict which both use __setval__ to
accept regular Python lists and dictionaries respectively).
If the value is not an instance of the same class as self, it raises
a RuntimeError.
Exceptions
|
|
RuntimeError( "You cannot assign a value to %s instance" % type( self ).__name__ )
|
|
|