From a869535b8bf4efb22c2c5e5c27537e9ec7f78dae Mon Sep 17 00:00:00 2001 From: Lukas Kulas Date: Thu, 4 Sep 2025 18:49:22 +0800 Subject: [PATCH 1/3] Create userdict entry for python --- .../terms/userdict/userdict.md | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 content/python/concepts/collections-module/terms/userdict/userdict.md diff --git a/content/python/concepts/collections-module/terms/userdict/userdict.md b/content/python/concepts/collections-module/terms/userdict/userdict.md new file mode 100644 index 00000000000..66630986e87 --- /dev/null +++ b/content/python/concepts/collections-module/terms/userdict/userdict.md @@ -0,0 +1,100 @@ +--- +Title: 'userdict' +Description: 'A wrapper around dictionary objects for easier dict subclassing.' +Subjects: +- +In Python, **userdict** is a class in the collections module that provides a wrapper around dictionary objects. It allows users to create custom dictionary-like classes by extending the userdict class and overriding its methods. This can be useful for creating specialized dictionaries with additional functionality or behavior. + +## Syntax + +```pseudo +from collections import UserDict + +class MyUserDict(UserDict): + def __init__(self, *args, **kwargs): + # underlying dict is stored in self.data + super().__init__(*args, **kwargs) + + def __setitem__(self, key, value): + # customize behavior, then delegate + super().__setitem__(key, value) + + def __getitem__(self, key): + # optional override + return super().__getitem__(key) + + def __delitem__(self, key): + super().__delitem__(key) + + def __missing__(self, key): + # optional: called when key is missing (if implemented) + raise KeyError(key) +``` + +## Examples + +- Basic wrapper usage + +```py +from collections import UserDict + +d = UserDict({"a": 1}) +d["b"] = 2 +print(d) # UserDict({'a': 1, 'b': 2}) +print(d.data) # {'a': 1, 'b': 2} +``` + +- Logging on set/delete + +```py +class LoggingDict(UserDict): + def __setitem__(self, key, value): + print(f"SET {key!r} = {value!r}") + super().__setitem__(key, value) + + def __delitem__(self, key): + print(f"DEL {key!r}") + super().__delitem__(key) +``` + +- Case-insensitive keys + +```py +class CaseInsensitiveDict(UserDict): + def _key(self, key): + return key.lower() if isinstance(key, str) else key + + def __setitem__(self, key, value): + super().__setitem__(self._key(key), value) + + def __getitem__(self, key): + return super().__getitem__(self._key(key)) +``` + +- Default-like behavior (simple alternative to defaultdict) + +```py +class DefaultUserDict(UserDict): + def __init__(self, default_factory=None, *args, **kwargs): + super().__init__(*args, **kwargs) + self.default_factory = default_factory + + def __missing__(self, key): + if self.default_factory is None: + raise KeyError(key) + self[key] = self.default_factory() + return self[key] +``` + +## Codebyte Example + +```codebyte/python +from collections import UserDict + +data = {'Pune':100, + 'Satara': 28, + 'Mumbai': 31} + +user_dict = UserDict(data) +print(user_dict.data) +``` From 266218a25a85ffd0a9b6f3cdd211bf6d4b1eb0cb Mon Sep 17 00:00:00 2001 From: Mamta Wardhani Date: Thu, 11 Sep 2025 17:20:09 +0530 Subject: [PATCH 2/3] added separate output blocks --- .../terms/userdict/userdict.md | 178 ++++++++++++------ 1 file changed, 119 insertions(+), 59 deletions(-) diff --git a/content/python/concepts/collections-module/terms/userdict/userdict.md b/content/python/concepts/collections-module/terms/userdict/userdict.md index 66630986e87..e5078895915 100644 --- a/content/python/concepts/collections-module/terms/userdict/userdict.md +++ b/content/python/concepts/collections-module/terms/userdict/userdict.md @@ -1,100 +1,160 @@ --- -Title: 'userdict' -Description: 'A wrapper around dictionary objects for easier dict subclassing.' +Title: 'UserDict' +Description: 'A wrapper class from collections that allows creating customized dictionary-like objects by subclassing it instead of dict.' Subjects: -- -In Python, **userdict** is a class in the collections module that provides a wrapper around dictionary objects. It allows users to create custom dictionary-like classes by extending the userdict class and overriding its methods. This can be useful for creating specialized dictionaries with additional functionality or behavior. + - 'Computer Science' + - 'Data Science' +Tags: + - 'Classes' + - 'Dictionary' + - 'Python' +CatalogContent: + - 'learn-python-3' + - 'paths/computer-science' +--- + +In Python, **`UserDict`** is a class in the `collections` module that provides a wrapper around dictionary objects. It allows creating custom dictionary-like classes by extending `UserDict` and overriding its methods, making it useful for building specialized dictionaries with additional functionality or behavior. ## Syntax ```pseudo +collections.UserDict([initialdata]) +``` + +**Parameters:** + +- `initialdata`: The `UserDict` constructor can take an optional dictionary or mapping object to initialize the data. + +**Return value:** + +Returns a dictionary-like object that can be subclassed to customize behavior. + +## Example 1: Subclassing `UserDict` + +In this example, a custom class is created by subclassing `UserDict` and overriding common dictionary methods. This shows how to extend and customize dictionary behavior: + +```py from collections import UserDict class MyUserDict(UserDict): - def __init__(self, *args, **kwargs): - # underlying dict is stored in self.data - super().__init__(*args, **kwargs) + def __setitem__(self, key, value): + print(f"Setting {key} = {value}") + super().__setitem__(key, value) - def __setitem__(self, key, value): - # customize behavior, then delegate - super().__setitem__(key, value) + def __getitem__(self, key): + print(f"Getting {key}") + return super().__getitem__(key) - def __getitem__(self, key): - # optional override - return super().__getitem__(key) +d = MyUserDict() +d["x"] = 42 +print(d["x"]) +``` - def __delitem__(self, key): - super().__delitem__(key) +The output is: - def __missing__(self, key): - # optional: called when key is missing (if implemented) - raise KeyError(key) +```shell +Setting x = 42 +Getting x +42 ``` -## Examples +## Example 2: Basic Wrapper Usage -- Basic wrapper usage +In this example, `UserDict` is used directly to wrap a dictionary. The `.data` attribute exposes the underlying dictionary object: ```py from collections import UserDict d = UserDict({"a": 1}) d["b"] = 2 -print(d) # UserDict({'a': 1, 'b': 2}) -print(d.data) # {'a': 1, 'b': 2} +print(d) +print(d.data) +``` + +The output is: + +```shell +UserDict({'a': 1, 'b': 2}) +{'a': 1, 'b': 2} ``` -- Logging on set/delete +## Example 3: Logging on Set/Delete + +In this example, dictionary modifications are logged by overriding `__setitem__` and `__delitem__`: ```py +from collections import UserDict + class LoggingDict(UserDict): - def __setitem__(self, key, value): - print(f"SET {key!r} = {value!r}") - super().__setitem__(key, value) + def __setitem__(self, key, value): + print(f"SET {key!r} = {value!r}") + super().__setitem__(key, value) + + def __delitem__(self, key): + print(f"DEL {key!r}") + super().__delitem__(key) + +d = LoggingDict() +d["name"] = "Aris" +del d["name"] +``` + +The output is: - def __delitem__(self, key): - print(f"DEL {key!r}") - super().__delitem__(key) +```shell +SET 'name' = 'Aris' +DEL 'name' ``` -- Case-insensitive keys +## Example 4: Case-Insensitive Keys + +In this example, keys are treated case-insensitively by normalizing them to lowercase before storing or retrieving: ```py +from collections import UserDict + class CaseInsensitiveDict(UserDict): - def _key(self, key): - return key.lower() if isinstance(key, str) else key + def _key(self, key): + return key.lower() if isinstance(key, str) else key + + def __setitem__(self, key, value): + super().__setitem__(self._key(key), value) - def __setitem__(self, key, value): - super().__setitem__(self._key(key), value) + def __getitem__(self, key): + return super().__getitem__(self._key(key)) - def __getitem__(self, key): - return super().__getitem__(self._key(key)) +d = CaseInsensitiveDict() +d["Name"] = "Mamta" +print(d["name"]) +print(d["NAME"]) ``` -- Default-like behavior (simple alternative to defaultdict) +The output is: -```py -class DefaultUserDict(UserDict): - def __init__(self, default_factory=None, *args, **kwargs): - super().__init__(*args, **kwargs) - self.default_factory = default_factory - - def __missing__(self, key): - if self.default_factory is None: - raise KeyError(key) - self[key] = self.default_factory() - return self[key] +```shell +Mamta +Mamta ``` -## Codebyte Example - -```codebyte/python -from collections import UserDict - -data = {'Pune':100, - 'Satara': 28, - 'Mumbai': 31} - -user_dict = UserDict(data) -print(user_dict.data) +## Codebyte Example: Default-Like Behavior + +In this example, a default factory is added, similar to `collections.defaultdict`, so missing keys automatically get initialized: + +```py +from collections import UserDict + +class DefaultUserDict(UserDict): + def __init__(self, default_factory=None, *args, **kwargs): + super().__init__(*args, **kwargs) + self.default_factory = default_factory + + def __missing__(self, key): + if self.default_factory is None: + raise KeyError(key) + self[key] = self.default_factory() + return self[key] + +d = DefaultUserDict(list) +d["a"].append(10) +print(d) ``` From 55029925b27c8bb30f70351def17189d3460db32 Mon Sep 17 00:00:00 2001 From: Mamta Wardhani Date: Thu, 11 Sep 2025 17:21:32 +0530 Subject: [PATCH 3/3] Update userdict.md --- .../concepts/collections-module/terms/userdict/userdict.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/python/concepts/collections-module/terms/userdict/userdict.md b/content/python/concepts/collections-module/terms/userdict/userdict.md index e5078895915..460e73d9b24 100644 --- a/content/python/concepts/collections-module/terms/userdict/userdict.md +++ b/content/python/concepts/collections-module/terms/userdict/userdict.md @@ -13,7 +13,7 @@ CatalogContent: - 'paths/computer-science' --- -In Python, **`UserDict`** is a class in the `collections` module that provides a wrapper around dictionary objects. It allows creating custom dictionary-like classes by extending `UserDict` and overriding its methods, making it useful for building specialized dictionaries with additional functionality or behavior. +In Python, **`UserDict`** is a class in the `collections` module that provides a wrapper around [dictionary](https://www.codecademy.com/resources/docs/python/dictionaries) objects. It allows creating custom dictionary-like classes by extending `UserDict` and overriding its methods, making it useful for building specialized dictionaries with additional functionality or behavior. ## Syntax