Type or key restricted and resettable dictionary
Project description
rsdict
rsdict is a restricted and resetable dictionary,
a subclass of dict (inherits from built-in dictionary).
>>> from rsdict import rsdict
>>> d = {"foo": 0, "bar": "baz"}
>>> rd = rsdict(d)
>>> rd
rsdict({'foo': 0, 'bar': 'baz'}, frozen=False, fixkey=True, fixtype=True, cast=False)
# fixkey=True: key restriction
>>> rd["newkey"] = 1
AttributeError
# fixtype=True: type restriction
>>> rd["foo"] = "str.value"
TypeError
>>> rd["foo"] = 999
>>> rd == d
False
# reset values to initial
>>> rd.reset()
>>> rd == d
True
Installation
pip install rsdict
Features
- Type-restrict(able): If activated, every type of value is fixed to its initial type.
- Key-restrict(able): If activated, cannot add or delete keys.
- Resettable: to initial value(s).
Arguments
rsdict(items, frozen=False, fixkey=True, fixtype=True, cast=False)
- items (dict): Initial items (data). Built-in dictionary only. kwargs are not supported.
- frozen (bool, optional): If True, the instance will be frozen (immutable).
- fixkey (bool, optional): If True, cannot add or delete keys.
- fixtype (bool, optional): If True, cannot change type of keys.
- cast (bool, optional): If False, cast to initial type (if possible). If True, allow only the same type of initial value.
Subclasses
# rsdict(frozen=True) as default
from rsdict import rsdict_frozen as rsdict
# rsdict(fixkey=False, fixtype=False) as default
from rsdict import rsdict_unfix as rsdict
# rsdict(fixkey=True, fixtype=False) as default
from rsdict import rsdict_fixkey as rsdict
# rsdict(fixkey=False, fixtype=True) as default
from rsdict import rsdict_fixtype as rsdict
Additional methods
set(key, value): Alias of__setitem__.to_dict() -> dict: Convert to dict instance.reset(key: Optional[Any]) -> None: Reset value to the initial value. If key is None, reset all values.is_changed(key: Optional[Any]) -> bool: If True, the values are changed from initial. If key is not None, check the key only.get_initial(key: Optional[Any]) -> dict | Any: Return initial value(s). If key is None, Return dict of all initial values.
Examples
Create (Initialize)
>>> from rsdict import rsdict
>>> d = dict(
... name = "John",
... enable = True,
... count = 0,
... )
>>> rd = rsdict(d)
>>> rd
rsdict({'name': 'John', 'enable': True, 'count': 0},
frozen=False, fixkey=True, fixtype=False)
>>> type(rd) is dict
False
>>> isinstance(rd, dict)
True
>>> rd.frozen
False
Get
Same as dict.
>>> rd["count"] == d["count"]
True
>>> rd["xyz"]
KeyError
>>> rd.get("count") == d.get("count")
True
>>> rd.get("xyz")
None
Set
>>> rd["enable"] = False
>>> rd.set("enable", False)
# If frozen, always raise an exception.
>>> rd_frozen = rsdict(d, frozen=True)
>>> rd_frozen["count"] = 2
AttributeError
# If fixtype and not cast, different-type value raise an exception.
>>> rd["count"] = "2"
TypeError
# If fixtype and cast, cast value to initial type.
>>> rd_cast = rsdict(d, cast=True)
>>> rd_cast["count"] = "2"
>>> rd_cast["count"]
2
>>> rd_cast["count"] = "abc"
ValueError
# If not fixtype, anything can be set.
>>> rd_typefree = rsdict(d, fixtype=False)
>>> rd_typefree["count"] = "2"
>>> rd_typefree["count"]
'2'
# If fixkey, setting with a new key raises an exception.
>>> rd["location"] = 9
AttributeError
# If not fixkey, a new key can be set.
>>> rd_keyfree = rsdict(d, fixkey=False)
>>> rd_keyfree["location"] = 9
>>> rd_keyfree["location"]
9
Delete
# If frozen or fixkey, deleting key raises an exception.
>>> del rd["count"]
AttributeError
# Else, delete both current and initial values.
>>> rd_keyfree = rsdict(dict(a=1, b=2, c=3), fixkey=False)
>>> del rd_keyfree["b"]
>>> rd_keyfree.keys()
dict_keys(['a', 'c'])
>>> rd_keyfree.get_initial().keys()
dict_keys(['a', 'c'])
Reset
# Check whether the values are changed from initial.
>>> rd.is_changed()
False
# (Change some values.)
>>> rd["enable"] = False
>>> rd["count"] = 5
>>> rd.is_changed()
True
# Reset with a key.
>>> rd.reset("count")
>>> rd["count"]
0
>>> rd.is_changed()
True
# Reset all values.
>>> rd.reset()
>>> rd.is_changed()
False
Copy
# Create a new rsdict with different optional arguments.
# If reset, copy initial values only.
>>> rd["name"] = "Mike"
>>> rd2 = rd.copy(reset=True)
>>> rd2 == rd.get_initial()
True
# If frozen and not reset, copy current values as new initial values.
>>> rd3 = rd.copy(frozen=True)
>>> rd3
rsdict({'name': 'Mike', 'enable': True, 'count': 0},
frozen=True, fixkey=True, fixtype=False, cast=False)
>>> rd3 == rd
True
>>> rd3.get_initial() == rd.get_initial()
False
Compare
>>> rd1 = rsdict({"key1": 10, "key2": "abc"})
>>> rd2 = rsdict({"key1": 20, "key2": "abc"})
# Change current value.
>>> rd2["key1"] = 10
# Current values are equal.
>>> rd1 == rd2
True
# Initial values are not equal.
>>> rd1.get_initial() == rd2.get_initial()
False
# If compare with dict, use current values.
>>> d2 = rd2.to_dict()
>>> rd2 == d2
Union
(Python3.9 or later)
>>> rd = rsdict({"key1": 10, "key2": "abc"}, fixkey=False)
>>> d = {"key2": 20, "key3": False}
# Return: dict
>>> rd | d
{'key1': 10, 'key2': 20, 'key3': False}
>>> d | rd
{'key2': 'abc', 'key3': False, 'key1': 10}
>>> rd |= d
>>> rd
rsdict({'key1': 10, 'key2': 20, 'key3': False},
frozen=False, fixkey=False, fixtype=True, cast=False)
# Add initial values of new keys only.
>>> rd.get_initial()
{'key1': 10, 'key2': 'abc', 'key3': False}
Note
- Expected types of value:
int,float,str,bool,None,list,dict,tuple,pathlib.Path - Some types (e.g.
numpy.ndarray) cannot be cast. - Tested in Python3.5, 3.6, 3.7, 3.8, 3.9, 3.10.
- Only initial items are deepcopied.
>>> d = dict(a=[1])
>>> rd = rsdict(d)
>>> rd["a"].append(2)
>>> rd
rsdict({'a': [1, 2]}, frozen=False, fixkey=True, fixtype=True, cast=False)
>>> d
{'a': [1, 2]}
>>> rd.get_initial()
{'a': [1]}
Performance
rsdict is slower than dict
due to its additional checking.
Changelog
-> CHANGELOG.md
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rsdict-0.1.8.tar.gz.
File metadata
- Download URL: rsdict-0.1.8.tar.gz
- Upload date:
- Size: 9.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.7.1 importlib_metadata/4.10.1 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2990fc787da362c913508492bb3ddff66c683c4a725a3c28022242a8d79c797
|
|
| MD5 |
531ac769ea3c9d93efe8a046449fd2ca
|
|
| BLAKE2b-256 |
0b67ecd3489b3daf011d4f82ed7331e1b66ccbbadefeefb203ce1ac541dadd4a
|
File details
Details for the file rsdict-0.1.8-py3-none-any.whl.
File metadata
- Download URL: rsdict-0.1.8-py3-none-any.whl
- Upload date:
- Size: 8.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.7.1 importlib_metadata/4.10.1 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
746c12d16ac7015bd4f9c3817f4d858811b9f5ed5c55c2783c68fce4328401e2
|
|
| MD5 |
c0d7574a027740b5057a6ffc210ef412
|
|
| BLAKE2b-256 |
787b17022e37a08bcfa95bb0a5508881796d65befbf28c9f0bbfa59fd9013539
|