attrmap
is an open source tool with read-only protection to help users get rid of dictionary in Python.
attrmap
maps the dict
to an object of AttrMap
, so users can avoid using the annoying [""]
syntax.
Users are welcome to report issues or request new features.
The API references can be found here.
- 2023-10-06: Put the package on conda-forge (Issue #3).
- 2023-10-06: Fix the missing docs problem.
- 2022-12-20: Fix the annoying warning when creating an AttrMap instance.
- 2022-08-27: Add utilities for AttrMap, see docs.
- 2022-08-27: Add deprecated warnings.
- 2022-08-13: Fix the
delattr
bug, users can delete an item viadel obj.attr
when theAttrMap
object is modifiable. - 2022-08-13: Fix the improper use of type hint, now
attrmap
is available for python>=3.6. - 2022-08-13: Update the document.
You can install attrmap
via pip:
pip install -U attrmap
Assuming you have an instance of dict
, then you can build an object of AttrMap
as follows:
from attrmap import AttrMap
import attrmap.utils as au
CONFIGS = {
"attr1": 1,
"attr2": ["hello", " ", "world"],
"attr3": {
"subattr1": "subattr1",
"subattr2": {
"subsubattr1": "subsubattr1",
}
}
}
configs = AttrMap(CONFIGS)
# Set the object unmodifiable.
configs = au.convert_state(configs, read_only=True)
# Equivalent to:
# au.convert_state(configs, read_only=True)
print(configs) # The outputs is more human readable.
# Object Contains Following Attributes
# attr1: 1
# attr2: ['hello', ' ', 'world']
# attr3:
# subattr1: subattr1
# subattr2:
# subsubattr1: subsubattr1
You can also assign the attributes and their values in a more simple way:
# Assume you have import AttrMap
# Create an empty AttrMap object.
configs = AttrMap()
configs.attr1 = 1
configs.attr2 = ["hello", " ", "world"]
configs.attr3.subattr1 = "subattr1"
configs.attr3.subattr2.subsubattr1 = "subsubattr1"
print(configs)
# Object Contains Following Attributes
# attr1: 1
# attr2: ['hello', ' ', 'world']
# attr3:
# subattr1: subattr1
# subattr2:
# subsubattr2: subsubattr1
You can convert the AttrMap
object to Python dict
anytime:
configs_dict = au.todict(configs)
print(configs_dict)
# {'attr1': 1, 'attr2': ['hello', ' ', 'world'], 'attr3': {'subattr1': 'subattr1', 'subattr2': {'subsubattr1': 'subsubattr1'}}}
print(type(configs_dict))
# <class 'dict'>
# AttrMap object doesn't store the original dict.
print(id(configs_dict))
# 139881853477376
print(id(CONFIGS))
# 139881853478464
# But it do not change the items:
print(configs_dict == CONFIGS)
# True
attrmap
has the read-only
protection to protect you from unintentional modification:
# Assume you have the above AttrMap object named configs
# Now set the AttrMap object as read-only.
configs = au.convert_state(configs, read_only=True)
# Try to create a new attribute.
configs.attr4 = "unintentional modification"
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "/xxxx/attrmap.py", line 558, in __setattr__
# self._check_modifiable()
# File "/xxxx/attrmap.py", line 643, in _check_modifiable
# raise AttributeError(
# AttributeError: Modifying the attributes of a read-only AttrMap instance is not allowed.
# Try to modify the value of an existing attribute:
configs.attr1 = "unintentional modification"
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "/xxxx/attrmap.py", line 558, in __setattr__
# self._check_modifiable()
# File "/xxxx/attrmap.py", line 643, in _check_modifiable
# raise AttributeError(
# AttributeError: Modifying the attributes of a read-only AttrMap instance is not allowed.
The read-only
protection is quite useful when you use the AttrMap
object to store the configuration of any system, any unintentional modification is not allowed. If you want to update the attribute's value, just set the read_only
of the AttrMap
instance as False
via au.convert_state(obj, read_only=False)
.
If the AttrMap
object should be unmodifiable, setting the object as read-only is recommended.
You can also build an AttrMap
instance from a .json
or .yaml
file. For example, assume you have a file.json
file:
{
"language": ["python", "cpp", "java"],
"value": [["one", "two"]],
"structure":{
"tree":["left tree", "right tree"]
}
}
Then you can build AttrMap
object via:
from attrmap import AttrMap
configs = AttrMap(path2file="/PATH_TO_YOUR_DIRECTORY/file.json") # .yaml file works too.
print(configs)
# Object Contains Following Attributes
# language: ['python', 'cpp', 'java']
# value: [['one', 'two']]
# structure:
# tree: ['left tree', 'right tree']
NOTE: The read-only
protection should be explicitly enabled, AttrMap
assumes you are still setting the attributes and their values.
- The API reference is missing, I will try to fix it in the next few days.
- Attributes starting with
_
might be conflict withAttrMap
preserved methods/properties. Attributes can still be accessed via dict-style ([""]
), but the attribute-style will return the "protected" (not the term of python, only means it's not "public") method such as_build_from_dict
. - Some publicly available properties and methods are reserved, they can only accessed via the dict-style.
Open bash shell and execute:
bash -i ./auto_test.sh
AttrMap
is an open source tool under Apache 2.0 license.