Adapters are the standard way to extend and customize the library. Adapters operate at the object level (unlike constructs, which operate at the stream level), and are thus easy to write and more flexible. For more info see the adapter tutorial.

In order to write custom adapters, implement _decode and _encode:

classMyAdapter(Adapter):def_decode(self,obj,context,path):# called at parsing time to return a modified version of objpassdef_encode(self,obj,context,path):# called at building time to return a modified version of objpass

It’s a craft that requires skills and understanding of the internals of the library (which change over time).

Adapters should really be all you need and are much simpler to implement.

To make things faster, try using compilation feature, or pypy. The python-level classes are as fast as it gets, assuming generality.

The only reason you might want to write a custom class is to achieve something that’s not currently possible. This might be a construct that computes/corrects the checksum of data, altough that already exists. Or a compression, or hashing. These also exist. But surely there is something that was not invented yet. If you need a semantics modification to an existing class, you can post a feature request, or copy the code of existing class into your project and modify it.

There are at least two kinds of constructs: raw construct and subconstructs.

Deriving from class Subconstruct, these wrap an inner construct, inheriting it’s properties (name and flags). In their _parse and _build and _sizeof methods, they will call self.subcon._parse and self.subcon._build and self.subcon._sizeof respectively.

classMySubconstruct(Subconstruct):def__init__(self,subcon):self.name=subcon.nameself.subcon=subconself.flagbuildnone=subcon.flagbuildnoneself.flagembedded=subcon.flagembeddeddef_parse(self,stream,context,path):obj=self.subcon._parse(stream,context,path)# do something with objreturnobjdef_build(self,obj,stream,context,path):# do something with objreturnself.subcon._build(obj,stream,context,path)# return same value (obj) or a modified value# that will replace the context dictionary entrydef_sizeof(self,context,path):# if not overriden, defers to subcon sizereturnself.subcon._sizeof(context,path)