Accessing Data

As you have seen in the previous chapters of this documentation, documents need to be frozen in order to be directly accessed like a dictionary.

However there are also ways to retrieve and manipulate the data without the document being frozen. This chapter will show you all ways to interact with and manipulate your documents.

internal_* methods

Using the methods internal_get(), internal_set(), internal_delete() and internal_contains() you can get, set and delete values at any time, or check if the document contains them. Please note, that if the document is not frozen yet, the internal_get returns a COPY of the values inside, which means that none of the changes done to nested data structures (except for nested documents themself) will be reflected, so you need to use internal_set to write these changes back to the document.

If the document is already frozen, these methods act like the dict-like access or the .doc property access.

The method internal_access() returns a context manager which can be used to temporarily simulate a freeze on the document. You can then access the document like a dict, or use .doc to manipulate the document. After the context, the document will re-synchronize the internal state with all the changes you made. Please note that this can be potentially relatively expensive with big documents.

Dict-like access, .doc property, .items()

If the document was frozen with the freeze() method, the data gets copied into the .doc property, which is an ordinary dict which can also be directly accessed via item access on the document itself.

Please note that frozen documents can not be further merged or processed, the methods resolve_and_merge_references, process_vars and validate will raise exceptions on frozen documents. You can not un-freeze documents. If you need to temporarily have dict-like access to the document, use internal_access instead (see above).

The method items() returns the .doc property too.

Copying the data via .to_dict()

Calling to_dict() at any time on the document will return a dict containing the header as a key, and the document’s internal dict as a value. All sub-documents are also converted to dicts.

Hooks

You can also implement these hook methods on your classes, to manipulate the data during specific events of the lifecycle of the document:

_initialize_data_before_merge(self, data: dict) dict

May be used to initialize the document by adding / changing data.

Called before doing anything else in resolve_and_merge_references(). Use this for setting default values.

The internal data is passed as an argument and can be mutated. The changed data MUST be returned again.

_initialize_data_after_merge(self, data: dict) dict

May be used to initialize the document by adding / changing data.

Called after resolve_and_merge_references(). Use this for setting default values.

The internal data is passed as an argument and can be mutated. The changed data MUST be returned again.

_initialize_data_after_variables(self, data: dict) dict

May be used to initialize the document by adding / changing data.

Called after process_vars().

Use this for setting internal values based on processed values in the document. The internal data is passed as an argument and can be mutated. The changed data MUST be returned again.

_initialize_data_after_freeze(self)

May be used to initialize the document by adding / changing data.

Called after freeze().

Use this for setting internal values based on processed values in the document. You can access the data using the self.doc property or by getting it from self (self[...]).