PyTables User's Guide: Hierarchical datasets in Python - Release 1.3.2 | ||
---|---|---|
Prev | Chapter 4. Library Reference | Next |
Represents the set of attributes of a node (Leaf or Group). It provides methods to create new attributes, open, rename or delete existing ones.
Like in Group instances, AttributeSet instances make use of the natural naming convention, i.e. you can access the attributes on disk like if they were normal AttributeSet attributes. This offers the user a very convenient way to access (but also to set and delete) node attributes by simply specifying them like a normal attribute class.
Caveat emptor: All Python data types are supported. In particular, multidimensional numarray objects are saved natively as multidimensional objects in the HDF5 file. Python strings are also saved natively as HDF5 strings, and loaded back as Python strings. However, the rest of the data types including the Python scalar ones (i.e. Int, Long and Float) and more general objects (like NumPy or Numeric) are serialized using cPickle, so you will be able to correctly retrieve them only from a Python-aware HDF5 library. So, if you want to save Python scalar values and be able to read them with generic HDF5 tools, you should make use of scalar numarray objects (for example numarray.array(1, type=numarray.Int64)). In the same way, attributes in HDF5 native files will be always mapped into numarray objects. Specifically, a multidimensional attribute will be mapped into a multidimensional numarray and an scalar will be mapped into a scalar numarray (for example, an attribute of type H5T_NATIVE_LLONG will be read and returned as a numarray.array(X, type=numarray.Int64) scalar).
One more warning: because of the various potential difficulties in restoring a Python object stored in an attribute, you may end up getting a cPickle string where a Python object is expected. If this is the case, you may wish to run cPickle.loads() on that string to get an idea of where things went wrong, as shown in this example:
>>> import tables >>> >>> class MyClass(object): ... foo = 'bar' ... >>> # An object of my custom class. ... myObject = MyClass() >>> >>> h5f = tables.openFile('test.h5', 'w') >>> h5f.root._v_attrs.obj = myObject # store the object >>> print h5f.root._v_attrs.obj.foo # retrieve it bar >>> h5f.close() >>> >>> # Delete class of stored object and reopen the file. ... del MyClass, myObject >>> >>> h5f = tables.openFile('test.h5', 'r') >>> print h5f.root._v_attrs.obj.foo Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'str' object has no attribute 'foo' >>> # Let us inspect the object to see what is happening. ... print repr(h5f.root._v_attrs.obj) 'ccopy_reg\n_reconstructor\np1\n(c__main__\nMyClass\np2\nc__builtin__\nobject\np3\nNtRp4\n.' >>> # Maybe unpickling the string will yield more information: ... import cPickle >>> cPickle.loads(h5f.root._v_attrs.obj) Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'module' object has no attribute 'MyClass' >>> # So the problem was not in the stored object, ... # but in the *environment* where it was restored. ... h5f.close()
The parent node instance.
List with all attribute names.
List with system attribute names.
List with user attribute names.
Note that this class defines the __setattr__, __getattr__ and __delattr__ and they work as normally intended. Any scalar (string, ints or floats) attribute is supported natively as an attribute. However, (c)Pickle is automatically used so as to serialize other kind of objects (like lists, tuples, dicts, small NumPy/Numeric/numarray objects, ...) that you might want to save. If an attribute is set on a target node that already has a large number of attributes, a PerformanceWarning will be issued.
With these special methods, you can access, assign or delete attributes on disk by just using the next constructs:
leaf.attrs.myattr = "str attr" # Set a string (native support) leaf.attrs.myattr2 = 3 # Set an integer (native support) leaf.attrs.myattr3 = [3,(1,2)] # A generic object (Pickled) attrib = leaf.attrs.myattr # Get the attribute myattr del leaf.attrs.myattr # Delete the attribute myattr
Copy the user attributes (as well as certain system attributes) to where object. where has to be a Group or Leaf instance.
Return a list of attribute names of the parent node. attrset selects the attribute set to be used. A user value returns only the user attributes and this is the default. sys returns only the system attributes. all returns both the system and user attributes.
Rename an attribute.