Skip to content

Instantly share code, notes, and snippets.

@GaryLee
Created January 23, 2026 00:15
Show Gist options
  • Select an option

  • Save GaryLee/f268b39bcc91e8b01f1fc201bba5016f to your computer and use it in GitHub Desktop.

Select an option

Save GaryLee/f268b39bcc91e8b01f1fc201bba5016f to your computer and use it in GitHub Desktop.
A read-only merged dictionary class that can merge multiple dict-like objects.
import collections.abc
from typing import Any, Dict, Iterator, Union
class ReadOnlyMergedDict(collections.abc.Mapping):
"""
A read-only merged dictionary class that can merge multiple dict-like objects
"""
def __init__(self, *dicts: Dict[Any, Any]):
"""
Initialize ReadOnlyMergedDict
Args:
*dicts: Multiple dict-like objects
"""
self._dicts = list(dicts)
def add_dict(self, dict_obj: Dict[Any, Any]) -> None:
"""
Add a dict-like object to the merged dictionary
Args:
dict_obj: The dict-like object to be added
"""
self._dicts.append(dict_obj)
def gets(self, key: Any) -> Iterator[Any]:
"""
Search for the specified key in each dict-like object sequentially,
and return all found values using yield
Args:
key: The key to search for
Yields:
All corresponding values found in the dictionaries
"""
for d in self._dicts:
if key in d:
yield d[key]
def __getitem__(self, key: Any) -> Any:
"""
Get value by key
Args:
key: The key to search for
Returns:
The corresponding value
Raises:
KeyError: When the key is not found
"""
# Search each dictionary sequentially
for d in self._dicts:
if key in d:
return d[key]
# If not found in any dictionary, raise KeyError
raise KeyError(key)
def __iter__(self) -> Iterator[Any]:
"""
Return an iterator of all keys
"""
seen_keys = set()
for d in self._dicts:
for key in d:
if key not in seen_keys:
seen_keys.add(key)
yield key
def __len__(self) -> int:
"""
Return the number of unique keys
"""
all_keys = set()
for d in self._dicts:
all_keys.update(d.keys())
return len(all_keys)
def __repr__(self) -> str:
"""
String representation
"""
return f"ReadOnlyMergedDict({self._dicts})"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment