-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathdictable_dataclass.py
More file actions
75 lines (51 loc) · 1.73 KB
/
dictable_dataclass.py
File metadata and controls
75 lines (51 loc) · 1.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python
"""
A prototype of a decorator that adds an iterator to a dataclass
so it can be passed in to the dict() constructor to make a dict.
If this is thought to be useful it could be added to the dataclass
decorator itself, to give all decorators this functionality.
"""
from dataclasses import dataclass
class DataClassIterator:
"""
Iterator for dataclasses
This used the class' __dataclass_fields__ dict to iterate through the
fields and their values
"""
def __init__(self, dataclass_instance):
self.dataclass_instance = dataclass_instance
self.keys_iter = iter(dataclass_instance.__dataclass_fields__.keys())
def __iter__(self):
return self
def __next__(self):
key = next(self.keys_iter)
return (key, getattr(self.dataclass_instance, key))
def _dunder_iter(self):
"""
function used as the __iter__ method in the dictable_dataclass decorator
"""
return DataClassIterator(self)
def dictable_dataclass(the_dataclass):
"""
class decorator for making a dataclass iterable in a way that is compatible
with the dict() constructor
"""
the_dataclass.__iter__ = _dunder_iter
return the_dataclass
# Example from the dataclass docs:
@dictable_dataclass
@dataclass
class InventoryItem:
'''Class for keeping track of an item in inventory.'''
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
if __name__ == "__main__":
# try it out:
inv_item = InventoryItem("sneakers", 50.0, 20)
print("an InventoryItem:\n", inv_item)
print()
print("And the dict you can make from it:")
print(dict(inv_item))