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 nested object attribute/dict member.
nested_updattr Update dict / class.dict of nested attributes.
nested_hasattr Check whether recursive object attributes/dict members exist.
nested_delattr Delete nested object attributes/dict members.
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.3.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nattrs-0.2.3-py3-none-any.whl (19.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: nattrs-0.2.3.tar.gz
  • Upload date:
  • Size: 13.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.9.6 Darwin/23.6.0

File hashes

Hashes for nattrs-0.2.3.tar.gz
Algorithm Hash digest
SHA256 0fa840fd39b9af3727f6e35c2ac3edc70c2abccb57b6b86fde9fd3ad23a7ed02
MD5 316aef6d24197e4fca43c5d49267ef9a
BLAKE2b-256 1616b50193738a18cf6e6c15b952c1ba215535baa7754623fd6b3c1090381679

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nattrs-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 19.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.9.6 Darwin/23.6.0

File hashes

Hashes for nattrs-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 7cc8e45f230c4f20ad6ddb73334469c07d4eef0d52b60c74897efa1d01810461
MD5 8e1b253b018ad8497cf5585cbaef1e41
BLAKE2b-256 c76ece20ddcbe853448d31b7a0ac6fbd2b5841d91456b77fde9e1d0e1930789e

See more details on using hashes here.

Supported by

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