.. _philosophy: Philosophy ========== Why :py:`nob`? The idea for this package came from long frustrating hours of working with deep nested data and configuration files. Let's start with an example --------------------------- Suppose you're working with this file: .. code-block:: yaml root: System: Library: Frameworks: Python.framework: Versions: 2.7: bin: python2.7 If you wanted the last value here from pure Python, you would have to write: .. code-block:: python pure_python['root']['System']['Library']['Frameworks']['Python.framework']['Versions']['2.7']['bin'] Gosh that's bad, it doesn't even fit in the screen! With :py:`nob`, this becomes: .. code-block:: python nob_object['bin'][:] Pretty neat, no? Mission statement ----------------- :py:`nob` is a wrapper that facilitates access and writes in JSON-serializable Python objects (a.k.a nested objects, or nobs). It leads to much lighter code when dealing with deep, complex nobs. It does this all while trying to stay close to native Python object's APIs. A nob is: **a dict of dicts** Most dict methods work everywhere (even if the tree is a list), with one notable exception: iteration works like lists, not dicts (see :ref:`iteration`). **a robust memory holder** You can reference any sub-tree, work with it in a pythonic way (including writing to it), and everything will affect the main tree seamlessly. **a pathfinder** Terse calls to keys deep in the tree are often enought to pinpoint the location you want to work with. As always, this comes with a price: * You will see some :py:`[:]` symbols cropping up everywhere, so you better get used to it :). * Smart calls in deep trees can trigger recursive searches and be expensive * Some extreme edge cases are not handled as well as native Python types If you think this cost/benefit balance could be good for you, please read on! See you in the :ref:`quickstart` section.