Skip to main content

Nested attribute getter/setter that works with dictionaries and objects interchangeably.

Project description

nattrs

Nested attributes utility functions for python. Allows getting/setting of object attributes and dict members interchangeably. Useful to populate nested dicts for storing outputs of a loop.

Alpha stage. Subject to change.

https://pypi.python.org/pypi/nattrs/

Installation

Install from pip:

pip install nattrs

Install from GitHub:

python -m pip install git+https://github.com/ludvigolsen/nattrs

Main functions

Class/Function Description
nested_getattr Get object attributes/dict members recursively, given by dot-separated names
nested_setattr Set object attribute/dict member by recursive lookup, given by dot-separated names.
nested_mutattr Apply function (mutate) to object attribute/dict member by recursive lookup, given by dot-separated names.
nested_hasattr Check whether recursive object attributes/dict members exist.
populate_product Create and populate nested dicts with specified layers and the same leaf value.

Examples

Create class B with a dict c with the member d:

class B:
    def __init__(self):
        self.c = {
            "d": 1
        }

Add to a dict a:

a = {"b": B()}

nested_getattr

Get the value of d:

nested_getattr(a, "b.c.d")
>> 1

Get default value when not finding an attribute:

nested_getattr(a, "b.o.p", default="not found")
>> "not found"

nested_setattr

Set the value of d:

nested_setattr(a, "b.c.d", 2)

Check new value of d:

nested_getattr(a, "b.c.d")
>> 2

nested_mutattr

Mutate d with an anonymous function (lambda):

nested_mutattr(a, "b.c.d", lambda x: x * 5)

Check new value of d:

nested_getattr(a, "b.c.d")
>> 10

Note: If your function performs the assignment in-place, remember to enable the is_inplace_fn argument.

nested_hasattr

Check presence of the member 'd':

nested_hasattr(a, "b.c.d")
>> True

Fail to find member 'o':

nested_hasattr(a, "b.o.p")
>> False

populate_product

In this example, we wish to pre-populate nested dicts with empty lists to allow appending within a for loop. First, we go through the manual approach of doing this. Second, we show how easy it is to do with populate_product().

Say we have 3 variables that can each hold 2 values. We want to compute something for each combination of these values. Let's first define these variables and their options:

animal = ["cat", "dog"]
food = ["strawberry", "cucumber"]
temperature = ["cold", "warm"]

Let's generate the product of these options:

import itertools

combinations = list(itertools.product(*[animal, food, temperature]))
combinations
>> [('cat', 'strawberry', 'cold'),
>>  ('cat', 'strawberry', 'warm'),
>>  ('cat', 'cucumber', 'cold'),
>>  ('cat', 'cucumber', 'warm'),
>>  ('dog', 'strawberry', 'cold'),
>>  ('dog', 'strawberry', 'warm'),
>>  ('dog', 'cucumber', 'cold'),
>>  ('dog', 'cucumber', 'warm')]

Now we can create a nested dict structure with a list in the leaf element:

# Initialize empty dict
nested_dict = {}

for leaf in combinations:
    # Join each string with dot-separation:
    attr = ".".join(list(leaf))

    # Assign empty list to the leafs
    # `make_missing` creates dicts for each 
    # missing attribute/dict member
    nattrs.nested_setattr(
        obj=nested_dict,
        attr=attr,
        value=[],
        make_missing=True
    )

nested_dict
>> {'cat': {'strawberry': {'cold': [], 'warm': []},
>>          'cucumber':   {'cold': [], 'warm': []}},
>>  'dog': {'strawberry': {'cold': [], 'warm': []},
>>          'cucumber':   {'cold': [], 'warm': []}}}

This dict population is actually provided by populate_product(). Instead of an empty list, let's set the value to an "edibility" score that could be changed by a later function:

layers = [animal, food, temperature]
populate_product(
    layers=layers,
    val=False
)
>> {'cat': {'strawberry': {'cold': False, 'warm': False},
>>          'cucumber':   {'cold': False, 'warm': False}},
>>  'dog': {'strawberry': {'cold': False, 'warm': False},
>>          'cucumber':   {'cold': False, 'warm': False}}}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nattrs-0.1.1.tar.gz (6.0 kB view hashes)

Uploaded Source

Built Distribution

nattrs-0.1.1-py3-none-any.whl (7.4 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page