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.

The functions should work with most dict types (i.e. Mapping / MutableMapping) and classes.

Tip: Attribute names can be found using regular expressions.

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

Installation

Install from PyPI:

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_updattr Update dict / class.dict of attributes recursively, given by dot-separated names.
nested_hasattr Check whether recursive object attributes/dict members exist.
nested_delattr Delete object attributes/dict members recursively, given by dot-separated names.
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_updattr

Update d with a dictionary:

nested_updattr(a, "b.c.d", {"d": 3})

Check new value of d:

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

Note: Also work on class.__dict__ dicts.

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

nested_delattr

Delete the member 'd':

nested_delattr(a, "b.c.d")
nested_hasattr(a, "b.c.d")
>> False

Ignore that it fails to find member 'o':

nested_delattr(a, "b.o.p", allow_missing=True)

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.2.2.tar.gz (14.0 kB view details)

Uploaded Source

Built Distribution

nattrs-0.2.2-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file nattrs-0.2.2.tar.gz.

File metadata

  • Download URL: nattrs-0.2.2.tar.gz
  • Upload date:
  • Size: 14.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.4.0 CPython/3.9.6 Darwin/21.6.0

File hashes

Hashes for nattrs-0.2.2.tar.gz
Algorithm Hash digest
SHA256 533686a410dd9facbb4c83b74b0894a947ca9cd279becc436f0ae0080ca0f3f0
MD5 a0590b967ccd827f996d30b61e23f741
BLAKE2b-256 4049d18ef6c24e2a0723ae2b116ebb74726e358256450f952eccfe7b433fe658

See more details on using hashes here.

File details

Details for the file nattrs-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: nattrs-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 20.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.4.0 CPython/3.9.6 Darwin/21.6.0

File hashes

Hashes for nattrs-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 3fe1294c4a2e1c7e5772fc37908e64940072a93c1d3c722c6f6b95dbeddf23c3
MD5 06105524b75eb08a0643bf6f0e666ab7
BLAKE2b-256 4cd6052ff5356a1f1c54f88709c0697253727dcc6cfedc74cf0090d660375f50

See more details on using hashes here.

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